C#比较两个不同对象的列表

时间:2015-04-09 22:38:14

标签: c# list

我看到Quickest way to compare two List<>,但我无法适应我的情况。我的问题是列表的类型不同。

我的列表是这样的:

List<Type1> firstList;
List<Type2> secondList;

以下是我现在所拥有的:

foreach (Type1 item in firstList)
{
    if (!secondList.Any(x => x.Id == item.Id))
    {
        // this code is executed on each item in firstList but not in secondList
    }
}
foreach (Type2 item in secondList)
{
    if (!firstList.Any(x => x.Id == item.Id))
    {
        // this code is executed on each item in secondList but not in firstList
    }
}

这是有效的,但是O(n^2)。有没有办法让这个更有效率?我上面提到的问题中的解决方案是使用.Except,但它不会使用lambda。

编辑: 我在上面提到了这一点,但这仍然被标记为重复。我没有两个相同对象的列表。我有两个不同对象的列表。 Type1和Type2是不同的类型。他们都有一个我需要匹配的ID。

3 个答案:

答案 0 :(得分:1)

我建议将2种类型的ID转换为2种HashSets。那你可以

HashSet<int> a = new HashSet<int>(firstList.Select(o => o.Id));

HashSet<int> b = new HashSet<int>(secondList.Select(o => o.Id));
if (a.IsSubsetOf(b) && b.IsSubsetOf(a))
{
    //Do your thing
}

答案 1 :(得分:0)

Except - 方法有一个重载,它以IEqualityComparer<T>作为最后一个参数。

MSDN中有一个示例:https://msdn.microsoft.com/en-us/library/bb336390.aspx

修改
可以创建匿名对象列表并将其与特殊IEqualityComparer<T>进行比较。这是比较器类:

class MyEqualityComparer : IEqualityComparer<object>
{
    #region IEqualityComparer<object> Members

    bool IEqualityComparer<object>.Equals(object x, object y)
    {
        return (x as dynamic).Id == (y as dynamic).Id;
    }

    int IEqualityComparer<object>.GetHashCode(object obj)
    {
        return ((obj as dynamic).Id as object).GetHashCode();
    }

    #endregion
}

LINQ表达式应如下所示:

var result = lst1.Select(x => new { Id = x.Id, Obj = x })
    .Except(lst2.Select(x => new { Id = x.Id, Obj = x }),
            new MyEqualityComparer())
    .Select(x => (x as dynamic).Obj as Type1);

我知道,在这种情况下使用动态是一种不好的风格,你可以毫无问题地将它改为实际类型。

答案 2 :(得分:0)

我不确定可用的C#/ Linq方法。从算法的角度来看,您可以对两个列表进行排序(通常为O(n*log(n)))。然后你只需要扫描列表(线性,又名O(m+n),其中m是列表1中的元素数量,n列表2中的元素数量)。假设列表1是较长的列表,则总复杂度为O(m*log(m))。 根据C#HashSet的实现,Murdock的答案可能会更快。