Comparing two List <string> for equality

Besides, that iterates over the elements one step at a time, how to compare two lists of strings for equality (in .NET 3.0):

This fails:

// Expected result. List<string> expected = new List<string>(); expected.Add( "a" ); expected.Add( "b" ); expected.Add( "c" ); // Actual result actual = new List<string>(); actual.Add( "a" ); actual.Add( "b" ); actual.Add( "c" ); // Verdict Assert.IsTrue( actual == expected ); 
+56
equality comparison collections c #
10 Oct '09 at 3:14
source share
8 answers

Many test environments offer the CollectionAssert class:

 CollectionAssert.AreEqual(expected, actual); 

Eg MS Test

+40
Oct 10 '09 at 3:32
source share

Try to execute

 var equal = expected.SequenceEqual(actual); 

Test Version

 Assert.IsTrue( actual.SequenceEqual(expected) ); 

The SequenceEqual extension method will compare collection items for equality.

See http://msdn.microsoft.com/en-us/library/bb348567(v=vs.100).aspx

+73
Oct 10 '09 at 3:20
source share

You can always write the desired function yourself:

 public static bool ListEquals<T>(IList<T> list1, IList<T> list2) { if (list1.Count != list2.Count) return false; for (int i = 0; i < list1.Count; i++) if (!list1[i].Equals(list2[i])) return false; return true; } 

and use it:

 // Expected result. List<string> expected = new List<string>(); expected.Add( "a" ); expected.Add( "b" ); expected.Add( "c" ); // Actual result actual = new List<string>(); actual.Add( "a" ); actual.Add( "b" ); actual.Add( "c" ); // Verdict Assert.IsTrue( ListEquals(actual, expected) ); 
+12
Oct 10 '09 at 3:51
source share

I noticed that no one actually told you why your source code is not working. This is due to the fact that the == operator in general tests refers to equality (i.e., if both instances point to the same object in memory), if only the operator was overloaded . List<T> does not define the == operator, so the base reference used is equal to implementation.

As other posters have shown, you usually have to go through the elements to check the "equality of collection." Of course, you should use the optimization suggested by the DreamWalker user, which first checks the number of collections before going through them.

+10
Oct 10 '09 at 4:04
source share

If order matters:

 bool equal = a.SequenceEquals(b); 

If the order doesn't matter:

 bool equal = a.Count == b.Count && new HashSet<string>(a).SetEquals(b); 
+5
Jan 21 '16 at 11:24
source share

You can write an extension method as follows:

 public static class ListExtensions { public static bool IsEqual<T>(this IList<T> list,IList<T> target, IComparer<T> comparer) where T:IComparable<T> { if (list.Count != target.Count) { return false; } int index = 0; while (index < list.Count && comparer.Compare(list[index],target[index]) == 0) { index++; } if (index != list.Count) { return false; } return true; } } 

And call it that:

 List<int> intList = new List<int> { 1, 234, 2, 324, 324, 2 }; List<int> targetList = new List<int> { 1, 234, 2, 324, 324 }; bool isEqual = intList.IsEqual(targetList, Comparer<int>.Default); 

EDIT: Updated code to use static method as OP uses .NET 3.0

 public static bool IsEqual<T>(IList<T> sourceList, IList<T> targetList, IComparer<T> comparer) where T : IComparable<T> { if (sourceList.Count != targetList.Count) { return false; } int index = 0; while (index < sourceList.Count && comparer.Compare(sourceList[index], targetList[index]) == 0) { index++; } if (index != sourceList.Count) { return false; } return true; } 

Client:

  bool isEqual = IsEqual(intList,targetList, Comparer<int>.Default); 
+1
Oct 10 '09 at 4:12
source share

Using Linq and writing code as an extension method:

 public static bool EqualsOtherList<T>(this List<T> thisList, List<T> theOtherList) { if (thisList == null || theOtherList == null || thisList.Count != theOtherList.Count) return false; return !thisList.Where((t, i) => !t.Equals(theOtherList[i])).Any(); } 
+1
Oct. 25 '15 at 2:56
source share

While iterating through the collection, this extension method that I created does not require the order of the two lists to be the same, and it also works with complex types if the Equals method is overridden.

The following two lists will return true:

 List<string> list1 = new List<string> { { "bob" }, { "sally" }, { "john" } }; List<string> list2 = new List<string> { { "sally" }, { "john" }, { "bob" } }; 

Method:

 public static bool IsEqualTo<T>(this IList<T> list1, IList<T> list2) { if (list1.Count != list2.Count) { return false; } List<T> list3 = new List<T>(); foreach (var item in list2) { list3.Add(item); } foreach (var item in list1) { int index = -1; for (int x = 0; x < list3.Count; x++) { if (list3[x].Equals(item)) { index = x; } } if (index > -1) { list3.RemoveAt(index); } else { return false; } } return !list3.Any(); } 
0
Sep 28 '15 at 14:25
source share



All Articles