比较两个List <string>是否相等
除了一个接一个地逐步遍历元素之外,我如何比较两个string列表是否相等(在.NET 3.0中):
这失败了:
// 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 );
提前致谢
许多testing框架提供了一个CollectionAssert类:
CollectionAssert.AreEqual(expected, actual);
如MStesting
尝试以下
var equal = expected.SequenceEqual(actual);
testing版本
Assert.IsTrue( actual.SequenceEqual(expected) );
SequenceEqual扩展方法将比较集合中的元素以便相等。
请参阅http://msdn.microsoft.com/en-us/library/bb348567(v=vs.100).aspx
你总是可以自己编写所需的函数:
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; }
并使用它:
// 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) );
我注意到没有人实际告诉你为什么你的原始代码不起作用。 这是因为==
运算符通常testing引用相等 (即,如果两个实例指向内存中的同一个对象),除非运算符已被重载 。 List<T>
没有定义一个==
运算符,因此使用基本引用equals实现。
正如其他海报所表明的那样,你通常必须通过元素来检验“收集平等”。 当然,你应该使用由用户DreamWalkerbuild议的优化,它首先testing集合的计数之前,通过它们。
如果订单很重要:
bool equal = a.SequenceEquals(b);
如果顺序无关紧要:
bool equal = a.Count == b.Count && new HashSet<string>(a).SetEquals(b);
你可以这样写一个扩展方法:
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; } }
并称之为如此:
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);
编辑:更新代码使用静态方法,因为OP是使用.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; }
客户:
bool isEqual = IsEqual(intList,targetList, Comparer<int>.Default);
使用Linq并将代码编写为扩展方法:
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(); }
虽然它迭代了集合,但是我创build的这个扩展方法并不要求两个列表的顺序相同,只要Equals方法被覆盖,它也可以处理复杂的types。
以下两个列表将返回true:
List<string> list1 = new List<string> { { "bob" }, { "sally" }, { "john" } }; List<string> list2 = new List<string> { { "sally" }, { "john" }, { "bob" } };
方法:
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(); }