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

C#中如何忽略顺序移除Tuple列表中的重复元素?

移除List<Tuple<int, int>>中顺序相反的重复项的高效实现方式

要处理这类元素相同但顺序相反的元组去重(比如(1,2)和(2,1)视为重复),以下是两种高效实现方案:

方案一:LINQ分组去重(简洁易读)

通过将每个元组标准化为「升序元素对」,再分组保留每组第一个元素,代码简洁直观:

var tupleList = new List<Tuple<int, int>>()
{
    new Tuple<int, int>(1, 2),
    new Tuple<int, int>(2, 1),
    new Tuple<int, int>(3, 2)
};

var uniqueTuples = tupleList
    .GroupBy(t => new { Min = Math.Min(t.Item1, t.Item2), Max = Math.Max(t.Item1, t.Item2) })
    .Select(group => group.First())
    .ToList();

// 最终结果:[(1,2), (3,2)]

原理:用Math.Min和Math.Max生成统一的键,让互为逆序的元组分到同一组,最终保留每组第一个出现的元组。时间复杂度为O(n log n),适合中小数据量场景。

方案二:HashSet+自定义比较器(性能最优)

通过自定义相等比较器,让HashSet识别互为逆序的元组为重复项,平均时间复杂度O(n),适合大数据量场景:

第一步:定义自定义比较器

public class ReverseTupleComparer : IEqualityComparer<Tuple<int, int>>
{
    public bool Equals(Tuple<int, int> x, Tuple<int, int> y)
    {
        // 判断元组是否完全相同或互为逆序
        return (x.Item1 == y.Item1 && x.Item2 == y.Item2) 
            || (x.Item1 == y.Item2 && x.Item2 == y.Item1);
    }

    public int GetHashCode(Tuple<int, int> obj)
    {
        // 让互为逆序的元组生成相同哈希码
        // 用元素和与积的组合确保哈希码一致
        return (obj.Item1 + obj.Item2).GetHashCode() ^ (obj.Item1 * obj.Item2).GetHashCode();
    }
}

第二步:用HashSet过滤重复项

var tupleList = new List<Tuple<int, int>>()
{
    new Tuple<int, int>(1, 2),
    new Tuple<int, int>(2, 1),
    new Tuple<int, int>(3, 2)
};

var uniqueSet = new HashSet<Tuple<int, int>>(new ReverseTupleComparer());
var uniqueTuples = new List<Tuple<int, int>>();

foreach (var t in tupleList)
{
    if (uniqueSet.Add(t))
    {
        uniqueTuples.Add(t);
    }
}

// 最终结果:[(1,2), (3,2)]

原理:自定义比较器让HashSet将互为逆序的元组判定为相等,遍历原列表时仅保留首次出现的非重复元组,哈希表的平均查找时间为O(1),整体性能更优。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:40:32