检查2个列表的快速方法是相同的c#

时间:2014-02-11 20:03:28

标签: c# linq ienumerable

假设有两个强类型列表:

列表1:现有项目

ID,Name,Cat
1,ABC,C
2,BCD,D
3,NNN,F

列表2:newitems

ID,姓名,猫
9,ABC,C
15,BCD,D
12,NNN,F

基本上,我想检查两个列表中的Name和Cat值是否相同。如果这两个列在这两列上相同,则返回true,否则返回false。

我尝试了一些主要在下面的变化,但似乎总是返回true,即使是newitems列表有一个新行,我希望返回false。

newitems.Any(x1 => existingitems.All(x2 => (x1.Name== x2.Name) && (x1.Cat== x2.Cat)));

4 个答案:

答案 0 :(得分:4)

我相信这对您来说可能是最干净,最简单的解决方案。

var list1Subset = list1.Select(i => new {i.Name, i.Cat});
var list2Subset = list2.Select(i => new {i.Name, i.Cat});

bool equal = list1Subset.SequenceEqual(list2Subset);

答案 1 :(得分:1)

您可以使用HashSet和自定义比较器有效地执行此操作:

public class ItemComparer : IEqualityComparer<Item>
{
    public bool Equals(Item x, Item y)
    {
        return (x.Cat == y.Cat) && (x.Name == y.Name);
    }

    public int GetHashCode(Item obj)
    {
        return (obj.Cat.GetHashCode() * 17) + (obj.Name.GetHashCode() * 17);
    }
}

public bool AreEqual(IEnumerable<T> set1, IEnumerable<T> set2, 
    IEqualityComparer<T> equalityComparer)
{
    // Handle cheapest cases
    if (set1 == null && set2 == null)
    {
        return true;
    }
    else if (set1 == null && set2 != null
        || set1 != null && set2 == null)
    {
        return false;
    }
    else if (object.ReferenceEquals(set1, set2))
    {
        return true;
    }

    var hashSet1 = new HashSet<T>(set1, equalityComparer);
    var hashSet2 = new HashSet<T>(set2, equalityComparer);

    // More easy cases
    if (hashSet1.Count != hashSet2.Count)
    {
        return false;
    }

    if (set1.Any(i => !hashSet2.Contains(i))
        || set2.Any(i => !hashSet1.Contains(i)))
    {
        return false;
    }

    return true;
}

答案 2 :(得分:0)

var areEqual = !existingitems.Select(x => new { x.Name, x, Cat })
                       .Except(newItems.Select(x => new { x.Name, x, Cat }))
                       .Any() 
             && !newItems.Select(x => new { x.Name, x, Cat })
                       .Except(existingitems.Select(x => new { x.Name, x, Cat }))
                       .Any();

var areEqual
     = newItems.Select(x => new { x.Name, x, Cat })
               .OrderBy(x => x.Name)
               .ThenBy(x => x.Cat)
               .SequanceEquals(existingitems.Select(x => new { x.Name, x, Cat })
                                       .OrderBy(x => x.Name)
                                       .ThenBy(x => x.Cat));

答案 3 :(得分:-1)

我们可以先定义一个方法来确定两个序列是否相等:

public static bool SetEquals<T>(this IEnumerable<T> first
    , IEnumerable<T> second
    , IEqualityComparer<T> comparer = null)
{
    comparer = comparer ?? EqualityComparer<T>.Default;
    return new HashSet<T>(second).SetEquals(first);
}

然后我们可以过滤掉您想要的字段并在该投影上执行设置相等:

var areEqual = list1.Select(item => new{item.Name, item.Cat})
    .SetEquals(list2.Select(item => new{item.Name, item.Cat}));