繁体   English   中英

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

[英]Quick way to check 2 lists are the same c#

假设有两个强类型列表:

清单1:现有项目

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

清单2:newitems

ID,姓名,Cat
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)));

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

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

您可以使用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;
}
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));

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM