1

I want to check if two lists contain the same items. The order of the items doesn't matter, and the same items might appear twice in each list.

For example:

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

Currently I do this as follows:

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

Now however I need to use an IEqualityComparer for the two items, which Remove cannot accept. Can anyone think of an efficient solution for the problem? It would also be useful if it accepted an IEnumerable rather than a List

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
Yair Halberstadt
  • 5,733
  • 28
  • 60

3 Answers3

5

Try this should work for your situation:

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

Just a temporary order then compare

Asakuraa Ranger
  • 577
  • 7
  • 18
0

Another option you could try is:

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));

This doesn't require a full sort and may return the results more quickly.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • What if `List2` has more keys than `List1`, you'd need to check both ways. – Lasse V. Karlsen Apr 25 '18 at 10:56
  • @LasseVågsætherKarlsen - Excellent point. It's an even better solution now with a simple `.Count` comparison at the beginning. No sense proceeding unless they are the same. – Enigmativity Apr 25 '18 at 13:52
-1

A solution that you could perhaps use is:

  1. Create 2 lists with distinct values of the original lists.
  2. Intersect the 2 distinct value lists into 1 list containing all distinct values.
  3. For each item in the combined distinct value list, count the amount of occurrences in each original list

Code:

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
}
Lennart
  • 752
  • 1
  • 5
  • 18