我想比较具有相同数量元素的两个列表,并找出它们之间的差异数。现在,我有这个代码(有效):
public static int CountDifferences<T> (this IList<T> list1, IList<T> list2)
{
if (list1.Count != list2.Count)
throw new ArgumentException ("Lists must have the same number of elements", "list2");
int count = 0;
for (int i = 0; i < list1.Count; i++) {
if (!EqualityComparer<T>.Default.Equals (list1[i], list2[i]))
count++;
}
return count;
}
这对我来说很麻烦,似乎必须有一种更优雅的方式来实现它。是否有办法将两个列表组合成单个元组列表,然后简单检查新列表的每个元素以查看两个元素是否相等?
答案 0 :(得分:2)
由于列表中的顺序确实计算在内,这将是我的方法:
public static int CountDifferences<T>(this IList<T> list1, IList<T> list2)
{
if (list1.Count != list2.Count)
throw new ArgumentException("Lists must have the same number of elements", "list2");
int count = list1.Zip(list2, (a, b) => a.Equals(b) ? 0 : 1).Sum();
return count;
}
简单地使用Enumerable.Zip()
合并列表然后总结差异,仍然是O(n),但这只列举了一次列表。
此方法也适用于同一类型的任何两个IEnumerable
,因为我们不使用列表索引器(除了显然在保护检查中的计数比较中)。
答案 1 :(得分:1)
尝试这样的事情:
var result = list1.Intersect(list2);
var differences = list1.Count - result.Count();
如果订单计数:
var result = a.Where((x,i) => x !=b[i]);
var differences = result.Count();
答案 2 :(得分:1)
我认为您的方法很好,但您可以使用LINQ来简化您的功能:
public static int CountDifferences<T>(this IList<T> list1, IList<T> list2)
{
if(list1.Count != list2.Count)
throw new ArgumentException("Lists must have same # elements", "list2");
return list1.Where((t, i) => !Equals(t, list2[i])).Count();
}
你在问题中写下它的方式,我认为Intersect
无法满足您的需求。例如,假设你有:
var list1 = new List<int> { 1, 2, 3, 4, 6, 8 };
var list2 = new List<int> { 1, 2, 4, 5, 6, 8 };
如果你运行list1.CountDifferences(list2)
,我假设你想要回到2,因为元素2和3是不同的。在这种情况下,Intersect
将返回5,因为列表共有5个元素。所以,如果你正在寻找5,那么Intersect
就是你要走的路。如果你想返回2,那么你可以使用上面的LINQ语句。
答案 3 :(得分:0)
您需要Enumerable的Intersect扩展方法。
public static int CountDifferences<T> (this IList<T> list1, IList<T> list2)
{
if (list1.Count != list2.Count)
throw new ArgumentException ("Lists must have the same number of elements", "list2");
return list1.Count - list1.Intersect(list2).Count();
}
答案 4 :(得分:0)
您可以使用List of List的扩展名方法。
List<int> lst1 = new List<int> { 1, 2, 3, 4, 5 };
List<int> lst2 = new List<int> { 6, 2, 9, 4, 5 };
int cntDiff = lst1.Zip(lst2, (a, b) => a != b).Count(a => a);
// Output is 2