找出两个列表之间的差异数量

时间:2011-04-23 05:07:02

标签: c# linq list comparison

我想比较具有相同数量元素的两个列表,并找出它们之间的差异数。现在,我有这个代码(有效):

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;
}

这对我来说很麻烦,似乎必须有一种更优雅的方式来实现它。是否有办法将两个列表组合成单个元组列表,然后简单检查新列表的每个元素以查看两个元素是否相等?

5 个答案:

答案 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