You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除List中所有符合特定条件的重复Edge元素

移除Edge列表中所有重复元素(含双向重复)

我有一个自定义的Edge类:

public class Edge
{
    public Vector3 a;
    public Vector3 b;

    public Edge(Vector3 a, Vector3 b)
    {
        this.a = a;
        this.b = b;
    }
}

需要移除列表中所有重复元素,满足以下任一条件即视为重复:

  • edge1.a == edge2.a && edge1.b == edge2.b
  • edge1.a == edge2.b && edge1.b == edge2.a

之前用带IEqualityComparer的Distinct()方法,它只会保留一个重复元素,但我需要把所有重复的元素全部移除,只留下没有任何重复的Edge。之前的尝试代码如下:

public class SomeClass: MonoBehaviour
{
    [SerializeField] private List<Edge> edges;

    private void Start()
    {
        edges = edges
            .Distinct(new EdgeComparer())
            .ToList();
        // 此代码移除重复项但保留一个,我需要将该元素也移除。
    }
}

public class EdgeComparer : IEqualityComparer<Edge>
{
    public bool Equals(Edge x, Edge y)
    {
        return
            (x.a.Equals(y.a) && x.b.Equals(y.b)) ||
            (x.a.Equals(y.b) && x.b.Equals(y.a));
    }

    public int GetHashCode(Edge obj)
    {
        int a = obj.a.GetHashCode();
        int b = obj.b.GetHashCode();

        return a ^ b;
    }
}

解决方案

要实现完全移除所有重复元素(包括重复组里的每一个),我们需要先按自定义规则统计每个Edge的出现次数,再筛选出仅出现一次的元素。

1. 优化EdgeComparer的哈希计算

原Comparer的GetHashCode用a ^ b存在哈希碰撞风险,调整后可以让(a,b)和(b,a)的哈希值更稳定一致:

public class EdgeComparer : IEqualityComparer<Edge>
{
    public bool Equals(Edge x, Edge y)
    {
        if (x == null || y == null) return x == y;
        return (x.a.Equals(y.a) && x.b.Equals(y.b)) || 
               (x.a.Equals(y.b) && x.b.Equals(y.a));
    }

    public int GetHashCode(Edge obj)
    {
        if (obj == null) return 0;
        int hashA = obj.a.GetHashCode();
        int hashB = obj.b.GetHashCode();
        // 让小哈希值在前,保证(a,b)和(b,a)的哈希值一致
        return hashA < hashB ? hashA ^ hashB : hashB ^ hashA;
    }
}

2. 分组筛选唯一元素

使用LINQ的GroupBy按自定义规则分组,再筛选出组内元素数量为1的项:

public class SomeClass: MonoBehaviour
{
    [SerializeField] private List<Edge> edges;
    private readonly EdgeComparer _edgeComparer = new EdgeComparer();

    private void Start()
    {
        edges = edges
            .GroupBy(edge => edge, _edgeComparer)
            .Where(group => group.Count() == 1)
            .Select(group => group.First())
            .ToList();
    }
}

逻辑说明

  • GroupBy:按照自定义的重复规则将所有Edge分组,同一个组内的元素都是互为重复的(包括双向情况)
  • Where(group => group.Count() == 1):只保留那些没有任何重复的分组(组内只有一个元素)
  • Select:从符合条件的分组中取出唯一的Edge元素
  • 最终列表仅包含完全没有重复的Edge,所有存在重复的元素组都被彻底移除

内容的提问来源于stack exchange,提问作者Ari Éowyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:31:05