如何使用LINQ确保多个集合具有相同的项数

6
有没有什么好的方法可以使用LINQ确保多个集合具有相同的项目数?
3个回答

2

试试这个:

bool sameLength = (collections.Select(c => c.Count())
                              .Distinct()
                              .Take(2)   // Optional (for optimization).
                              .Count()) == 1;

或者:

bool sameLength = !collections.Select(c => c.Count()).Distinct().Skip(1).Any();

它的工作原理是找到每个集合的长度并跟踪唯一值。一个不同的计数是可以的,但如果有两个(或更多)不同的计数,则所有集合的长度都不相同,因此结果为false。
更新:如果集合具有不同的类型,则可以使用非泛型接口,如此答案中所示。
var collections = new List<ICollection> { a, b, c, d };

1
集合?你是指我所有集合的聚合吗? - Yoann. B
我的集合不是同一类型的:List<double>,List<MyItem>等。但我需要比较所有列表的计数。 - Yoann. B
第一个选项真的很难读。我不想维护这段代码。第二个选项最好是 .Distinct().Count() == 1。我们会失去一些性能,但提高可读性。 - Dan Abramov
@gaearon:你对第二个方案的改进基本上就是再次使用了第一个方案,是吗? - Mark Byers
1
@gaearon:我的原始答案没有包括Take(2) - 如果你读了评论,你会发现我是在别人建议后才加上这个的。现在我已经做出了妥协,指出这行代码是可选的。如果性能更重要,那就使用它 - 如果可读性更重要,那就省略它。 - Mark Byers
显示剩余5条评论

2

检查

如果
collection1.Count() == collection2.Count()

请注意,这将枚举集合。如果集合枚举代价高昂(如LINQ2SQL)或会改变状态(更新一些数据和/或记录),那么使用LINQ就没有太好的方法。


2
“Count” 不总是枚举集合。对于 “ICollection”,据我所记,它在内部使用 “Count” 属性。 - Dan Abramov

2
如果你的所有集合都实现了ICollection接口,你可以将它们放入一个单独的List<ICollection>中,然后应用Mark的方法。
var a = new List<int>();
var b = new List<double>();
var c = new List<float>();
var d = new List<string>();

var collections = new List<ICollection> { a, b, c, d };
var sameLength = collections.Select(c => c.Count).Distinct().Count() == 1;

太好了。我只想说这段代码最好用.Distinct().Count() == 1来代替。虽然会牺牲一些性能,但可读性会更好。.Skip(1).Any()有点违反直觉。 - Dan Abramov
2
@gaearon:没错。由于我们正在使用ICollection.Count,如果集合数量较小,则不应有任何实质性的性能影响。但是当处理一些未知的集合时情况就不同了,这些集合只实现了IEnumerable<>接口。我会修改代码。 - mgronber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接