Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if one IEnumerable contains all elements of another IEnumerable

What is the fastest way to determine if one IEnumerable contains all the elements of another IEnumerable when comparing a field/property of each element in both collections?


public class Item {     public string Value;      public Item(string value)     {         Value = value;     } }  //example usage  Item[] List1 = {new Item("1"),new Item("a")}; Item[] List2 = {new Item("a"),new Item("b"),new Item("c"),new Item("1")};  bool Contains(IEnumerable<Item> list1, IEnumerable<Item>, list2) {     var list1Values = list1.Select(item => item.Value);     var list2Values = list2.Select(item => item.Value);      return //are ALL of list1Values in list2Values? }  Contains(List1,List2) // should return true Contains(List2,List1) // should return false 
like image 615
Brandon Zacharie Avatar asked Jul 18 '10 06:07

Brandon Zacharie


2 Answers

There is no "fast way" to do this unless you track and maintain some state that determines whether all values in one collection are contained in another. If you only have IEnumerable<T> to work against, I would use Intersect.

var allOfList1IsInList2 = list1.Intersect(list2).Count() == list1.Count(); 

The performance of this should be very reasonable, since Intersect() will enumerate over each list just once. Also, the second call to Count() will be optimal if the underlying type is an ICollection<T> rather than just an IEnumerable<T>.

like image 151
Kent Boogaart Avatar answered Oct 26 '22 17:10

Kent Boogaart


You could also use Except to remove from the first list all values that exist in the second list, and then check if all values have been removed:

var allOfList1IsInList2 = !list1.Except(list2).Any(); 

This method had the advantage of not requiring two calls to Count().

like image 25
J W Avatar answered Oct 26 '22 18:10

J W