Check if two lists have the same items

I have two lists, as shown below, how can I say that they have the same elements. Order is not important.

var list1 = new List<int> {1,2,3}; var list2 = new List<int> {2,1,3}; 

How can I say that they are equal? Should I write my own method or is there a built-in method for it?

+6
source share
5 answers

What sets (e.g. HashSet<T> ). Sets do not have a specific order, and SetEquals checks if the set and the other set contain the same elements.

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

You can use !Except + Any :

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

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

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

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

So, you had to do both checks if you wanted both lists to contain the same elements.

If you also want to consider that both lists are the same size, check list1.Count==list2.Count . But this check is not useful if you use the set method (see Harald's comment ), it makes no sense to compare counters if you ignore duplicates later.

In general, HashSet<T> has some good and effective methods for checking whether two sequences have the same elements (ignoring duplicates), dcastro already showed one.


If you want an effective solution to determine if two lists contain the same elements, the same number and not ignoring duplicates , but ignoring 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); } 

Using:

 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 and number of duplicates are calculated, use:

 bool sameItemsSameOrder = list1.SequenceEqual(list2); 
+7
source

You can try except

 var result = list1.Except(list2).ToList(); 

Except first returns those elements that are not displayed in the second

+1
source

What about:

 list1.Count == lis2.Count, then list1.Except(list2).Any() 

or perhaps (but probably not):

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

Edit: Rotem is correct. I misunderstood the question. This will work.

0
source

Without using linq.

  private static bool AreListsEqual(List<int> list1, List<int> list2) { var areListsEqual = true; if (list1.Count != list2.Count) return false; for (var i = 0; i < list1.Count; i++) { if (list2[i] != list1[i]) { areListsEqual = false; } } return areListsEqual; } 
0
source

Source: https://habr.com/ru/post/971220/


All Articles