我知道LINQ有SequenceEquals
方法。此方法确保每个集合中的每个项目值以相同的顺序匹配。
我正在寻找的是更“等效”的功能。只是两个序列包含相同的项目,不一定是相同的顺序。
例如,nUnit有CollectionAssert.AreEqual()
和CollectionAssert.AreEquivalent()
执行我正在解释的内容。
我知道我可以通过以下方式做到这一点:
SequenceEquals
Intersect
,然后查看交叉点是否等于原始序列。示例:
var source = new[] {5, 6, 7};
source.Intersect(new[] {5, 7, 6}).Count() == source.Length;
答案 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;
}