除了逐个单步执行元素之外,如何比较两个字符串列表是否相等(在.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 );
答案 0 :(得分:76)
尝试以下
var equal = expected.SequenceEqual(actual);
测试版
Assert.IsTrue( actual.SequenceEqual(expected) );
SequenceEqual扩展方法将比较集合的元素以保持相等。
请参阅http://msdn.microsoft.com/en-us/library/bb348567(v=vs.100).aspx
答案 1 :(得分:40)
答案 2 :(得分:12)
您可以随时自行编写所需的功能:
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) );
答案 3 :(得分:10)
我注意到没有人告诉你为什么你的原始代码不起作用。这是因为==
运算符一般测试reference equality(即,如果两个实例指向内存中的同一对象),除非运算符已overloaded。 List<T>
未定义==
运算符,因此使用了基本引用等于实现。
正如其他海报所展示的那样,你通常必须逐步通过元素来测试“集合平等”。当然,您应该使用用户DreamWalker建议的优化,该优化在逐步测试之前首先测试集合的Count。
答案 4 :(得分:5)
如果订单很重要:
bool equal = a.SequenceEquals(b);
如果订单无关紧要:
bool equal = a.Count == b.Count && new HashSet<string>(a).SetEquals(b);
答案 5 :(得分:1)
您可以编写如下的扩展方法:
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);
答案 6 :(得分:1)
使用Linq并将代码编写为扩展方法:
def fib(n):
if n == 0:
return [0]
elif n == 1:
return [0, 1]
else:
lst = fib(n-1)
lst.append(lst[-1] + lst[-2])
return lst
答案 7 :(得分:0)
虽然它会迭代集合,但我创建的这个扩展方法并不要求两个列表的顺序相同,只要重写了Equals方法,它也适用于复杂类型。
以下两个列表将返回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();
}
答案 8 :(得分:0)
它可能以非常规方式使用,但没有为自定义类型实现IEquatable
JsonConvert.SerializeObject( myList1) == JsonConvert.SerializeObject( myList2)
但是在一般情况下,您可以使用https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sequenceequal?view=netframework-4.8注释中提到的SequenceEqual
也不要忘记为自定义类型实现IEquatable接口(对于字符串类型或其他结构不是必需的)