Cri*_*scu 5 .net c# linq list set
可能重复:
比较两个集合是否相等
我需要验证两个IEnumerable<T>列表是否具有相同的元素,不一定是相同的顺序.
我的目标是.NET 3.5.
这是测试.问题是,应该如何HasSameElements()实施?
var l1 = new[]{1,2,3};
var l2 = new[]{3,1,2};
bool rez1 = l1.HasSameElements(l2);//should be true
var l3 = new[]{1,2,3,2};
var l4 = new[]{3,1,2,2};
bool rez2 = l3.HasSameElements(l4);//should be true
var l5 = new[]{1,2,3,2};
var l6 = new[]{1,2,3};
bool rez3 = l5.HasSameElements(l6);//should be false
Run Code Online (Sandbox Code Playgroud)
附加说明:
在示例中,我使用IEnumerable,但T可以是任何东西.T必须实施IComparable吗?
Enumerable.SequenceEquals()本身不起作用,它期望元素的顺序相同.
这是一个模板HasElements:
[只是一些占位符文本作为Markdown'代码格式'错误的解决方法]
public static class Extensions {
public static bool HasElements(this IEnumerable<T> l1, IEnumerable<T> l2){
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
尽管 Cristi 的Except基于 - 的方法显然更好,但您可能会逃脱:
source.Sort().SequenceEqual(target.Sort());
Run Code Online (Sandbox Code Playgroud)
如果是用于单元测试,我不会担心性能。当然,您需要确保您的排序是稳定的。
只需构建一个字典,将每个对象映射到它在序列中出现的次数,然后检查生成的字典是否相等。
这里:
static class EnumerableExtensions {
public static bool HasSameElementsAs<T>(
this IEnumerable<T> first,
IEnumerable<T> second
) {
var firstMap = first
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
var secondMap = second
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
return
firstMap.Keys.All(x =>
secondMap.Keys.Contains(x) && firstMap[x] == secondMap[x]
) &&
secondMap.Keys.All(x =>
firstMap.Keys.Contains(x) && secondMap[x] == firstMap[x]
);
}
}
Run Code Online (Sandbox Code Playgroud)
显然,重复的代码可以重构为辅助方法,但这只会混淆这里的想法。你可以让幻想和接受IEqualityComparer的GroupBy操作。此外,您应该通过添加null警卫和不添加什么来生产代码。