Check if two list have the same items

You can use !Except + Any:

bool list1InList2 = !list1.Except(list2).Any();

This checks not if both have the same items but if list1 is contained in list2(ignoring duplicates).

If you want to know if list2 is contained in list1, use:

bool list2InList1 = !list2.Except(list1).Any();

So you had to make both checks if you wanted to ensure that both lists contain the same items.

If you also want to take into account that both lists have the same size, precheck with list1.Count==list2.Count. But this check is not useful if you use a set method(see Harald's comment), it doesn't make much sense to compare the counts if you ignore duplicates afterwards.

In general HashSet<T> has some nice and efficient methods to check if two sequences have the same items(ignoring duplicates), dcastro already showed one.


If you want an efficient solution to determine if two lists contain the same items, same count and not ignoring duplicates but ignoring the order(otherwise use SequenceEquals):

public static bool SequenceEqualsIgnoreOrder<T>(this IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer = null)
{
    if(list1 is ICollection<T> ilist1 && list2 is ICollection<T> ilist2 && ilist1.Count != ilist2.Count)
        return false;

    if (comparer == null)
        comparer = EqualityComparer<T>.Default;

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

Usage:

var list1 = new List<int> { 1, 2, 3, 1 };
var list2 = new List<int> { 2, 1, 3, 2 };
bool sameItemsIgnoringOrder = list1.SequenceEqualsIgnoreOrder(list2); 
// false because same count and same items but 1 appaears twice in list1 but once in list2

If the order matters and duplicates count too, use:

bool sameItemsSameOrder = list1.SequenceEqual(list2);

That's what sets (e.g., HashSet<T>) are for. Sets have no defined order, and SetEquals verifies whether the set and another collection contain the same elements.

var set = new HashSet<int>(list1);
var equals = set.SetEquals(list2);

Tags:

C#

Linq

List