Does .NET have a way to check if List a contains all items in List b?

83,169

Solution 1

If you're using .NET 3.5, it's easy:

public class ListHelper<T>
{
    public static bool ContainsAllItems(List<T> a, List<T> b)
    {
        return !b.Except(a).Any();
    }
}

This checks whether there are any elements in b which aren't in a - and then inverts the result.

Note that it would be slightly more conventional to make the method generic rather than the class, and there's no reason to require List<T> instead of IEnumerable<T> - so this would probably be preferred:

public static class LinqExtras // Or whatever
{
    public static bool ContainsAllItems<T>(this IEnumerable<T> a, IEnumerable<T> b)
    {
        return !b.Except(a).Any();
    }
}

Solution 2

Included in .NET 4: Enumerable.All

public static bool ContainsAll<T>(IEnumerable<T> source, IEnumerable<T> values)
{
    return values.All(value => source.Contains(value));
}

Solution 3

Just for fun, @JonSkeet's answer as an extension method:

/// <summary>
/// Does a list contain all values of another list?
/// </summary>
/// <remarks>Needs .NET 3.5 or greater.  Source:  https://stackoverflow.com/a/1520664/1037948 </remarks>
/// <typeparam name="T">list value type</typeparam>
/// <param name="containingList">the larger list we're checking in</param>
/// <param name="lookupList">the list to look for in the containing list</param>
/// <returns>true if it has everything</returns>
public static bool ContainsAll<T>(this IEnumerable<T> containingList, IEnumerable<T> lookupList) {
    return ! lookupList.Except(containingList).Any();
}
Share:
83,169

Related videos on Youtube

Matt Haley
Author by

Matt Haley

Ruby on Rails programmer... learning C.

Updated on July 08, 2022

Comments

  • Matt Haley
    Matt Haley almost 2 years

    I have the following method:

    namespace ListHelper
    {
        public class ListHelper<T>
        {
            public static bool ContainsAllItems(List<T> a, List<T> b)
            {
                return b.TrueForAll(delegate(T t)
                {
                    return a.Contains(t);
                });
            }
        }
    }
    

    The purpose of which is to determine if a List contains all the elements of another list. It would appear to me that something like this would be built into .NET already, is that the case and am I duplicating functionality?

    Edit: My apologies for not stating up front that I'm using this code on Mono version 2.4.2.

    • Colonel Panic
      Colonel Panic over 8 years
    • Colonel Panic
      Colonel Panic over 8 years
      Your algorithm is quadratic O(nm). If the lists are sorted, testing if one is a subset of another should be possible in O(n+m) time.
  • Nils
    Nils over 14 years
    This is untested, but wouldn't return b.Except(a).Empty(); be much more readable ?
  • Peter Stephens
    Peter Stephens over 14 years
    Except that Empty() doesn't return a boolean. It returns an IEnumerable<T> with no items.
  • Matt Haley
    Matt Haley over 14 years
    This requires Linq right? If so, I don't think that's available in Mono, which is what I'm using at the moment.
  • Jon Skeet
    Jon Skeet over 14 years
    You can use LINQ to Objects in Mono, I believe... but it would be helpful if you'd state the requirements in the question to start with. Which version of Mono are you using?
  • Jon Skeet
    Jon Skeet over 14 years
    I've just checked the sources for Mono 2.4.2.3, and it definitely includes LINQ to Objects.
  • drzaus
    drzaus almost 11 years
    similarly: Contains Any = public static bool ContainsAny<T>(this IEnumerable<T> haystack, IEnumerable<T> needle) { return haystack.Intersect(needle).Count() > 0; }. I tried some quick performance comparisons to haystack.Count() - 1 >= haystack.Except(needle).Count(); and Intersect seemed to do better most of the time.
  • drzaus
    drzaus almost 11 years
    sheesh...use Any() not Count() > 0: public static bool ContainsAny<T>(this IEnumerable<T> haystack, IEnumerable<T> needle) { return haystack.Intersect(needle).Any(); }
  • Rohit Vipin Mathews
    Rohit Vipin Mathews over 8 years
    list l = new List<T>(check); I dont think this would compile and if it does, its totally unecessary as check is already a list
  • Colonel Panic
    Colonel Panic over 8 years
    If the lists are length n and m, what's the time complexity of this algorithm?
  • Jon Skeet
    Jon Skeet over 8 years
    @ColonelPanic: Assuming no hash collisions, O(n+m).
  • Bojan
    Bojan over 3 years
    If two lists are identical, this will return false, because there wouldn't be Any() elements found after the Except()
  • Jon Skeet
    Jon Skeet over 3 years
    @Bojan: No, it will return true, because the expression starts with !. See dotnetfiddle.net/QdXPy7 for a runnable example.