使用IEqualityComparer比较两个列表,其中顺序无关紧要

时间:2018-04-25 08:06:09

标签: c# linq

我想检查两个列表是否包含相同的项目。项目的顺序无关紧要,每个列表中相同的项目可能会出现两次。

例如:

var List1 = new List<int> { 1, 2, 2 };
var List2 = new List<int> { 2, 1, 2 };
//equal

var List1 = new List<int> { 1, 2, 2 };
var List2 = new List<int> { 2, 1, 1 };
//not equal - different quantities of 1s and 2s in the two lists

目前我这样做如下:

var List2copy = List2.ToList();
if (List1.Count != List2.Count) return false;
return List1.All(x => List2copy.Remove(x));

现在,我需要对IEqualityComparer无法接受的两个项目使用Remove。任何人都可以想到一个有效的解决方案吗?如果它接受IEnumerable而不是List

,它也会很有用

4 个答案:

答案 0 :(得分:3)

试试这个应该适合你的情况:

return ListA.OrderBy(x => x).SequenceEqual(ListB.OrderBy(x => x));

只是临时订单然后比较

答案 1 :(得分:0)

您可以尝试的另一个选择是:

var lookup1 = List1.ToLookup(x => x);
var lookup2 = List2.ToLookup(x => x);

return lookup1.Count == lookup2.Count && lookup1.All(x => lookup2[x.Key].SequenceEqual(x));

这不需要完整排序,可能会更快地返回结果。

答案 2 :(得分:-1)

这应该有效:

var List2copy = List2.ToList();
if (List1.Count != List2.Count) return false;
return List1.All(x =>
{
    int index = List2copy.FindIndex(y => new MyEqualityComparer<int>().Equals(x, y));
    if (index == -1) return false;
    List2copy.RemoveAt(index);
    return true;
});

答案 3 :(得分:-1)

您可以使用的解决方案是:

  1. 使用原始列表的不同值创建2个列表。
  2. 将2个不同的值列表与1个包含所有不同值的列表相交。
  3. 对于组合不同值列表中的每个项目,计算每个原始列表中的出现次数
  4. 代码:

    var list1 = new List<int>{1,2,2};
    var list2 = new List<int>{1,1,2};
    var list1Distinct = list1.Distinct();
    var list2Distinct = list1.Distinct();
    var allDistinctValues = list1.Intersect(list2);
    bool listsEqual = true;
    
    foreach(int i in allDistinctValues)
    {
        int list1Count=0;
        int list2Count=0;
        list1Count = list1.Count(val => val == i);
        list2Count = list2.Count(val => val == i);
        if(list1Count != list2Count)
        {
            listsEqual = false;
        }
    }
    
    if(!listsEqual)
    {
        //List item counts not the same
    }