【问题标题】:How to get all distinct combinations of pairs in C# / LINQ?如何在 C#/LINQ 中获得所有不同的对组合?
【发布时间】:2014-05-21 13:02:35
【问题描述】:

我有一个相同类型的对元组,例如:[1,1][1,2][2,1][2,1]

我需要计算不同的组合:[1,1][1,2]

public void DistinctPairsTest()
{
    IList<Tuple<int, int>> pairs = new List<Tuple<int, int>>();
    pairs.Add(Tuple.Create(1, 1));
    pairs.Add(Tuple.Create(1, 2));
    pairs.Add(Tuple.Create(2, 1));
    pairs.Add(Tuple.Create(2, 1));

    IList<Tuple<int, int>> distinctPairs = GetDistinctPairs(pairs);

    Assert.AreEqual(2, distinctPairs.Count);
}

private IList<Tuple<T, T>> GetDistinctPairs<T>(IList<Tuple<T, T>> pairs)
{
    throw new NotImplementedException();
}

您将如何实现通用 GetDistinctPairs(pairs) ?

解决方案:

正如 Heinzi 和 Dennis_E 建议的那样,我实现了一个通用的 IEqualityComparer。欢迎改进:-)

public class CombinationEqualityComparer<T> : IEqualityComparer<Tuple<T, T>>
{
    public bool Equals(Tuple<T, T> x, Tuple<T, T> y)
    {
        bool equals = new HashSet<T>(new[] { x.Item1, x.Item2 }).SetEquals(new[] { y.Item1, y.Item2 });
        return equals;
    }

    public int GetHashCode(Tuple<T, T> obj)
    {
        return obj.Item1.GetHashCode() + obj.Item2.GetHashCode();
    }
}

【问题讨论】:

  • 你可以让 Equals 更短: return (Equals(x.Item1, y.Item1) && Equals(x.Item2, y.Item2)) || (等于(x.Item1, y.Item2) && 等于(x.Item2, y.Item1))。我不是实现 GetHashCode() 的专家,但人们经常使用素数来乘以,否则 [a,b] 将始终给出与 [b,a] 相同的哈希码。所以,类似:return obj.Item1.GetHashCode() * 31 + obj.Item2.GetHashCode();
  • @Dennis_E:这是设计使然:在这种情况下,[a, b] 应该给出与 [b, a] 相同的哈希码,因为 Equals([a, b], [b, a]) 返回真的。 IEqualityComparer<T>.GetHashCode 的文档说:“需要实现以确保如果 Equals 方法为两个对象 x 和 y 返回 true,则 GetHashCode 方法为 x 返回的值必须等于为 y 返回的值。"
  • 当然! (拍了拍额头)
  • 更短的实现是return new HashSet&lt;T&gt;(new[] {x.Item1, x.Item2}).SetEquals(new[] {y.Item1, y.Item2}); 但是,这可能更适合代码高尔夫......
  • 不错!我更新了解决方案

标签: c# linq


【解决方案1】:

有一个Enumerable.Distinct overload 允许您指定一个IEqualityComparer

提供一个认为 [1, 2] 和 [2, 1] 相等的自定义 IEqualityComparer&lt;Tuple&lt;T, T&gt;&gt;

实现应该是微不足道的,留给读者作为练习。 :-)

【讨论】:

  • 很好的答案!谢谢!
【解决方案2】:

您可以编写一个实现 IEqualityComparer&lt;Tuple&lt;int, int&gt;&gt; 的类并在调用 Distinct() 时使用它:

pairs.Distinct(new YourComparerClass());

【讨论】:

  • 谢谢。不幸的是,@Heinzi 更准确一些(尽管答案几乎完全相同)
  • Okidoki。我们同时回答。 (经常发生)
猜你喜欢
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多