为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

白衣染霜花 2019-07-19 18:42:27
比较两个List<T>对象是否相等,忽略顺序还有一个清单-比较问题。List<MyType> list1;List<MyType> list2;我需要检查它们是否具有相同的元素,而不管它们在列表中的位置如何。各MyType对象可能多次出现在列表中。有没有一个内置的函数来检查这个?如果我保证每个元素只在一个列表中出现一次呢?
查看完整描述

3 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

如果您希望它们是真正相等的(即相同的项和每个项的数目),我认为最简单的解决方案是在比较之前进行排序:

Enumerable.SequenceEqual(list1.OrderBy(t => t), list2.OrderBy(t => t))

编辑:

下面是一个性能更好的解决方案(大约快10倍),并且只需要IEquatable,不是IComparable:

public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2) {
  var cnt = new Dictionary<T, int>();
  foreach (T s in list1) {
    if (cnt.ContainsKey(s)) {
      cnt[s]++;
    } else {
      cnt.Add(s, 1);
    }
  }
  foreach (T s in list2) {
    if (cnt.ContainsKey(s)) {
      cnt[s]--;
    } else {
      return false;
    }
  }
  return cnt.Values.All(c => c == 0);}

编辑2:

若要将任何数据类型作为键(例如,正如Frank Tzanabetis指出的可空类型)处理,您可以创建一个采用比较器词典:

public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer) {
  var cnt = new Dictionary<T, int>(comparer);
  ...


查看完整回答
反对 回复 2019-07-19
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

正如所写的那样,这个问题是模棱两可的。声明:

..无论它们在列表中的位置如何,它们都有相同的元素。每个MyType对象可能在列表中出现多次。

不指示是否要确保这两个列表具有同集对象或相同的不同集.

如果要确保集合具有一点儿没错无论顺序如何,都可以使用相同的一组成员:

// lists should have same count of items, and set difference must be emptyvar areEquivalent = (list1.Count == list2.Count) && !list1.Except(list2).Any();

如果要确保两个集合具有相同的不同成员集(其中两个集合中的重复项都被忽略),可以使用:

// check that [(A-B) Union (B-A)] is emptyvar areEquivalent = !list1.Except(list2).Union( list2.Except(list1) ).Any();

使用SET操作(IntersectUnionExcept)比使用以下方法更有效Contains..在我看来,它也更好地表达了您的查询的期望。

编辑:既然你已经澄清了你的问题,我可以说你想用第一种形式-因为重复很重要。下面是一个简单的示例,说明您得到了所需的结果:

var a = new[] {1, 2, 3, 4, 4, 3, 1, 1, 2};var b = new[] { 4, 3, 2, 3, 1, 1, 1, 4, 2 };// result below should be true, since the two sets are equivalent...var areEquivalent = (a.Count() == b.Count()) && !a.Except(b).Any();


查看完整回答
反对 回复 2019-07-19
?
森栏

TA贡献1810条经验 获得超5个赞

如果你不关心发生的次数,我会这样对待它。与简单的迭代相比,使用散列集将提供更好的性能。

var set1 = new HashSet<MyType>(list1);var set2 = new HashSet<MyType>(list2);return set1.SetEquals(set2);

这将要求您已重写.GetHashCode()并付诸实施IEquatable<MyType>在……上面MyType.


查看完整回答
反对 回复 2019-07-19
  • 3 回答
  • 0 关注
  • 1699 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信