是否有LINQ等效方法?

时间:2010-09-21 13:33:43

标签: c# .net linq

我知道LINQ有SequenceEquals方法。此方法确保每个集合中的每个项目值以相同的顺序匹配。

我正在寻找的是更“等效”的功能。只是两个序列包含相同的项目,不一定是相同的顺序。

例如,nUnit有CollectionAssert.AreEqual()CollectionAssert.AreEquivalent()执行我正在解释的内容。

我知道我可以通过以下方式做到这一点:

  1. 提前订购列表并使用SequenceEquals
  2. 使用Intersect,然后查看交叉点是否等于原始序列。
  3. 示例:

    var source = new[] {5, 6, 7};
    source.Intersect(new[] {5, 7, 6}).Count() == source.Length;
    

3 个答案:

答案 0 :(得分:9)

您可以构建一个集合,然后使用HashSet<T>.SetEquals。它并不严格地在LINQ中,但它与它很好地搭配:)

当然,您可以轻松编写自己的扩展方法来扩展它。像这样:

public static bool SetEquals<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
    HashSet<T> hashSet = new HashSet<T>(source);
    return hashSet.SetEquals(other); // Doesn't recurse! Calls HashSet.SetEquals
}

编辑:正如评论中所述,这忽略了元素出现的次数以及排序 - 因此{ 1, 2 }将“设置为等于”{ 1, 2, 1, 2, 1, 1, 1 }。如果这不是你想要的,它会变得更复杂。

答案 1 :(得分:8)

我会创建一个执行交叉的扩展方法,然后比较计数。

答案 2 :(得分:2)

我是这样做的:

public static bool SetEquivalent<T>(
    this IEnumerable<T> aSet,
    IEnumerable<T> anotherSet)
{
    var diffA = aSet.Except(anotherSet).Count();
    var diffB = anotherSet.Except(aSet).Count();
    return diffA == diffB && diffA == 0;
}