C #: how do you check lists with the same sizes and the same elements?

There are two line lists

List<string> A; List<string> B; 

What is the shortest code you would assume in order to verify that A.Count == B.Count and each element A in B and vice versa: each B is in (elements A and elements B can have a different order).

+6
c # algorithm linq
source share
6 answers

If you don't need to worry about duplicates:

 bool equal = new HashSet<string>(A).SetEquals(B); 

If you are worried about duplicates, this becomes a little more uncomfortable. This will work, but it is relatively slow:

 bool equal = A.OrderBy(x => x).SequenceEquals(B.OrderBy(x => x)); 

Of course, you can make both options more efficient by first checking the score, which is a simple expression. For example:

 bool equal = (A.Count == B.Count) && new HashSet<string>(A).SetEquals(B); 

... but you provided the shortest code :)

+25
source share
 A.Count == B.Count && new HashSet<string>(A).SetEquals(B); 

If different duplicate frequencies are a problem, check out this question .

+2
source share

If you call Enumerable.Except () on these two lists, it returns an IEnumerable<string> containing all the elements that are in one list, but not the other. If the counter is 0, then you know that the two lists are the same.

+1
source share

If you are not interested in duplicates, or you are concerned about duplicates, but not too concerned about optimizing performance, then the various methods in John's answer are certainly suitable.

If duplicates and performance bother you, then something like this extension method should do the trick, although it really doesn’t meet your “shortest code” criteria!

 bool hasSameElements = A.HasSameElements(B); // ... public static bool HasSameElements<T>(this IList<T> a, IList<T> b) { if (a == b) return true; if ((a == null) || (b == null)) return false; if (a.Count != b.Count) return false; var dict = new Dictionary<string, int>(a.Count); foreach (string s in a) { int count; dict.TryGetValue(s, out count); dict[s] = count + 1; } foreach (string s in b) { int count; dict.TryGetValue(s, out count); if (count < 1) return false; dict[s] = count - 1; } return dict.All(kvp => kvp.Value == 0); } 

(Note that this method will return true if both sequences are null . If this is not the desired behavior, then it is easy enough to add additional null checks.)

0
source share
 var result = A.Count == B.Count && A.Where(y => B.Contains(y)).Count() == A.Count; 

May be,?

0
source share

How about a simple loop?

 private bool IsEqualLists(List<string> A, List<string> B) { for(int i = 0; i < A.Count; i++) { if(i < B.Count - 1) { return false; } else { if(!String.Equals(A[i], B[i]) { return false; } } } return true; } 
0
source share

All Articles