Other than stepping through the elements one by one, how do I compare two lists of strings for equality (in .NET 3.0):
This fails:
// Expected re
Try the following
var equal = expected.SequenceEqual(actual);
Test Version
Assert.IsTrue( actual.SequenceEqual(expected) );
The SequenceEqual extension method will compare the elements of the collection in order for equality.
See http://msdn.microsoft.com/en-us/library/bb348567(v=vs.100).aspx
It might be used with not regular way but without implementation IEquatable for Custom types
JsonConvert.SerializeObject( myList1) == JsonConvert.SerializeObject( myList2)
But in general case you could use SequenceEqual as was mentioned in comments https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sequenceequal?view=netframework-4.8
Also do not forget to implement IEquatable interface for custom types (not necessary for strings type or other structure)
You could write an extension method like so:
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 like so:
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 the code to use a static method instead since OP is using .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);
You can always write the needed function themselves:
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) );
If the 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);
While it does iterate over the collection, this extension method I created does not require the order of the two lists to be the same, and it works with complex types as well, as long as the Equals method is overridden.
The following two lists would 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();
}