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

如何在C#的List中移除无序重复的整数对?

解决C#中无序整数对的去重问题

嗨,作为C#新手遇到这种情况太正常啦!默认的Distinct()方法确实没法识别(2,3)和(3,2)这种无序重复对,因为它是严格按照结构体的每个字段顺序来判断相等性的。咱们来一步步搞定这个问题~

方法一:修改FaceLine结构体,实现相等性判断

最直接的方式是让FaceLine自己知道什么是“无序相等”,这需要我们重写相等性相关的方法,并且实现IEquatable<FaceLine>接口(推荐,因为比object版本的Equals效率更高)。

具体代码如下:

using System;

public struct FaceLine : IEquatable<FaceLine>
{
    public int A;
    public int B;

    // 核心:判断两个FaceLine是否是无序相等
    public bool Equals(FaceLine other)
    {
        // 两种情况:要么顺序完全一致,要么交换A/B后一致
        return (A == other.A && B == other.B) || (A == other.B && B == other.A);
    }

    // 重写object的Equals方法,调用上面的强类型版本
    public override bool Equals(object obj)
    {
        return obj is FaceLine other && Equals(other);
    }

    // 必须重写GetHashCode,保证无序对的哈希值相同
    // 否则Distinct会因为哈希值不同,根本不会调用Equals方法
    public override int GetHashCode()
    {
        // 取A和B中的最小值和最大值,组合成固定顺序的键
        int min = Math.Min(A, B);
        int max = Math.Max(A, B);
        // 用Tuple的哈希实现,简单可靠
        return Tuple.Create(min, max).GetHashCode();
    }
}

写完之后,直接调用Distinct()就可以自动去重了:

var uniqueFaceLines = faceline.Distinct().ToList();

方法二:自定义相等比较器(不修改结构体)

如果你不想改动FaceLine结构体的代码,可以给Distinct()传入一个自定义的IEqualityComparer<FaceLine>,专门用来判断无序相等。

先写比较器类:

using System;
using System.Collections.Generic;

public class FaceLineEqualityComparer : IEqualityComparer<FaceLine>
{
    public bool Equals(FaceLine x, FaceLine y)
    {
        return (x.A == y.A && x.B == y.B) || (x.A == y.B && x.B == y.A);
    }

    public int GetHashCode(FaceLine obj)
    {
        int min = Math.Min(obj.A, obj.B);
        int max = Math.Max(obj.A, obj.B);
        return Tuple.Create(min, max).GetHashCode();
    }
}

使用的时候,把比较器传给Distinct():

var uniqueFaceLines = faceline.Distinct(new FaceLineEqualityComparer()).ToList();

小测试验证

用你提供的示例数据来测试一下:

var faceline = new List<FaceLine>
{
    new FaceLine { A = 1, B = 2 },
    new FaceLine { A = 2, B = 3 },
    new FaceLine { A = 3, B = 1 },
    new FaceLine { A = 3, B = 2 }, // 和(2,3)重复
    new FaceLine { A = 2, B = 4 },
    new FaceLine { A = 4, B = 3 }
};

var uniqueList = faceline.Distinct().ToList();
// 最终uniqueList里会剩下:(1,2)、(2,3)、(3,1)、(2,4)、(4,3),正好去掉了重复的(3,2)

两种方法的小总结

  • 方法一适合长期使用这个结构体的场景,所有地方调用Distinct()都会自动生效;
  • 方法二更灵活,适合临时需要去重的场景,不用修改原有结构体代码。

内容的提问来源于stack exchange,提问作者johnny_vonri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:36