比较两个List<T>对象是否相等,忽略顺序

比较两个List<T>对象是否相等,忽略顺序

还有一个清单-比较问题。

List<MyType> list1;List<MyType> list2;

我需要检查它们是否具有相同的元素,而不管它们在列表中的位置如何。各MyType对象可能多次出现在列表中。有没有一个内置的函数来检查这个?如果我保证每个元素只在一个列表中出现一次呢?


白衣染霜花
浏览 405回答 3
3回答

撒科打诨

如果您希望它们是真正相等的(即相同的项和每个项的数目),我认为最简单的解决方案是在比较之前进行排序:Enumerable.SequenceEqual(list1.OrderBy(t&nbsp;=>&nbsp;t),&nbsp;list2.OrderBy(t&nbsp;=>&nbsp;t))编辑:下面是一个性能更好的解决方案(大约快10倍),并且只需要IEquatable,不是IComparable:public&nbsp;static&nbsp;bool&nbsp;ScrambledEquals<T>(IEnumerable<T>&nbsp;list1,&nbsp;IEnumerable<T>&nbsp;list2)&nbsp;{ &nbsp;&nbsp;var&nbsp;cnt&nbsp;=&nbsp;new&nbsp;Dictionary<T,&nbsp;int>(); &nbsp;&nbsp;foreach&nbsp;(T&nbsp;s&nbsp;in&nbsp;list1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cnt.ContainsKey(s))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt[s]++; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt.Add(s,&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;} &nbsp;&nbsp;foreach&nbsp;(T&nbsp;s&nbsp;in&nbsp;list2)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cnt.ContainsKey(s))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt[s]--; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;} &nbsp;&nbsp;return&nbsp;cnt.Values.All(c&nbsp;=>&nbsp;c&nbsp;==&nbsp;0);}编辑2:若要将任何数据类型作为键(例如,正如Frank Tzanabetis指出的可空类型)处理,您可以创建一个采用比较器词典:public&nbsp;static&nbsp;bool&nbsp;ScrambledEquals<T>(IEnumerable<T>&nbsp;list1,&nbsp;IEnumerable<T>&nbsp;list2,&nbsp;IEqualityComparer<T>&nbsp;comparer)&nbsp;{ &nbsp;&nbsp;var&nbsp;cnt&nbsp;=&nbsp;new&nbsp;Dictionary<T,&nbsp;int>(comparer); &nbsp;&nbsp;...

茅侃侃

正如所写的那样,这个问题是模棱两可的。声明:..无论它们在列表中的位置如何,它们都有相同的元素。每个MyType对象可能在列表中出现多次。不指示是否要确保这两个列表具有同集对象或相同的不同集.如果要确保集合具有一点儿没错无论顺序如何,都可以使用相同的一组成员://&nbsp;lists&nbsp;should&nbsp;have&nbsp;same&nbsp;count&nbsp;of&nbsp;items,&nbsp;and&nbsp;set&nbsp;difference&nbsp;must&nbsp;be&nbsp;emptyvar&nbsp;areEquivalent&nbsp;=&nbsp;(list1.Count&nbsp;==&nbsp;list2.Count)&nbsp;&&&nbsp;!list1.Except(list2).Any();如果要确保两个集合具有相同的不同成员集(其中两个集合中的重复项都被忽略),可以使用://&nbsp;check&nbsp;that&nbsp;[(A-B)&nbsp;Union&nbsp;(B-A)]&nbsp;is&nbsp;emptyvar&nbsp;areEquivalent&nbsp;=&nbsp;!list1.Except(list2).Union(&nbsp;list2.Except(list1)&nbsp;).Any();使用SET操作(Intersect,&nbsp;Union,&nbsp;Except)比使用以下方法更有效Contains..在我看来,它也更好地表达了您的查询的期望。编辑:既然你已经澄清了你的问题,我可以说你想用第一种形式-因为重复很重要。下面是一个简单的示例,说明您得到了所需的结果:var&nbsp;a&nbsp;=&nbsp;new[]&nbsp;{1,&nbsp;2,&nbsp;3,&nbsp;4,&nbsp;4,&nbsp;3,&nbsp;1,&nbsp;1,&nbsp;2};var&nbsp;b&nbsp;=&nbsp;new[]&nbsp;{&nbsp;4,&nbsp;3,&nbsp;2,&nbsp;3,&nbsp;1,&nbsp;1,&nbsp;1,&nbsp;4,&nbsp;2&nbsp;};//&nbsp;result&nbsp;below&nbsp;should&nbsp;be&nbsp;true,&nbsp;since&nbsp;the&nbsp;two&nbsp;sets&nbsp;are&nbsp;equivalent...var&nbsp;areEquivalent&nbsp;=&nbsp;(a.Count()&nbsp;==&nbsp;b.Count())&nbsp;&&&nbsp;!a.Except(b).Any();

跃然一笑

如果你不关心发生的次数,我会这样对待它。与简单的迭代相比,使用散列集将提供更好的性能。var&nbsp;set1&nbsp;=&nbsp;new&nbsp;HashSet<MyType>(list1);var&nbsp;set2&nbsp;=&nbsp;new&nbsp;HashSet<MyType>(list2);return&nbsp;set1.SetEquals(set2);这将要求您已重写.GetHashCode()并付诸实施IEquatable<MyType>在……上面MyType.
打开App,查看更多内容
随时随地看视频慕课网APP