如何比较两个通用集合[重复]

Posted

技术标签:

【中文标题】如何比较两个通用集合[重复]【英文标题】:How can I compare two generic collections [duplicate] 【发布时间】:2016-03-03 20:53:48 【问题描述】:

我有两个名为barcodesSource 和barcodesTarget 的通用集合。他们都是同类型的Helper。我想根据属性 BARCODE 将名为barcodesSource 的集合与第二个集合进行比较,并仅返回第一个集合中的数据,而第二个集合中没有对应的 BARCODE。

谁能告诉我解决办法?

class Helper

    public long BARCODE  get; set; 
    public int ITEM  get; set; 



List<Helper> barcodesSource = new List<Helper>();
List<Helper> barcodesTarget = new List<Helper>();

var distinctBarcodes = barcodesSource.Where(a => barcodesTarget.All(b => b.BARCODE != a.BARCODE));

【问题讨论】:

可能是一个 LINQ Intersect? 看看这个答案,可能会有帮助***.com/a/7244729/1195872 【参考方案1】:

一种选择是使用集合操作,即

var result = new HashSet<Helper>(barcodesSource);
result.ExceptWith(barcodesTarget);

【讨论】:

【参考方案2】:

您可以使用 LINQ .Except() 方法和自定义 Comparer 类:

   class Helper
    
        public string barCode;
    

    class MyComparer : IEqualityComparer<Helper>
    
        public bool Equals(Helper x, Helper y)
        
            return x.barCode == y.barCode;
        

        public int GetHashCode(Helper obj)
        
            return obj.GetHashCode();
        
    

    class Class1
    
        static void Main()
        
            List<Helper> bcs1 = new List<Helper>()
            
                new Helper()  barCode = "0001" ,
                new Helper()  barCode = "0002" ,
                new Helper()  barCode = "0003" ,
                new Helper()  barCode = "0004" 
            ;

            List<Helper> bcs2 = new List<Helper>()
            
                new Helper()  barCode = "0001" ,
                new Helper()  barCode = "0002" ,
                new Helper()  barCode = "0003" 
            ;

            bcs1 = bcs1.Except(bcs2, new MyComparer()).ToList();

            Console.WriteLine(bcs1.Count);    
            Console.WriteLine(bcs1.First().barCode);

            Console.ReadKey();
        
    

输出: 1 0004

【讨论】:

而不是 return base.GetHashCode();return BARCODE.GetHashCode(); 因为 OP 只关心 BARCODE 值而不是 Helper 类的相应 ITEM 值。 @JenishRabadiya 好点,虽然 OP 只是想获得两个集合之间的差异【参考方案3】:

您可以在 Lambda 表达式中使用 Join 来获取相同的 Helper 对象。

barcodesSource.Join(barcodesTarget, x=> new x.BARCODE, x.ITEM, y=> new y.BARCODE, y.ITEM, (x,y)=> x);

你可以使用这个辅助方法来获取不同的对象:

public static IEnumerable<TOuter> NotJoin<TOuter, TInner, TKey>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector)
    where TInner : class
    where TOuter : class

    IEnumerable<TOuter> results = from o in outer join i in inner on outerKeySelector(o) equals innerKeySelector(i) into joinData from left in joinData.DefaultIfEmpty() where left == null select o;
    return results;


barcodesSource.NotJoin(barcodesTarget, x=> new x.BARCODE, x.ITEM, y=> new y.BARCODE, y.ITEM);

【讨论】:

【参考方案4】:

使用HashSet&lt;&gt;.Contains 的另一种基于集合的方法:

var barcodes = new HashSet<long>(barcodesTarget.Select(b => b.BARCODE));
var distinctBarcodes = barcodesSource.Where(a => !barcodes.Contains(a.BARCODE));

【讨论】:

谢谢。它解决了我的问题。【参考方案5】:

使用Any:

var distinctBarcodes = barcodesSource.Where(a => !barcodesTarget.Any(b => b.BARCODE == a.BARCODE));

【讨论】:

不知道为什么这会得到如此多的赞成,因为它会产生O(N2)(或接近)的复杂性,这是不可取的,如果两个集合都很大,可能会导致性能问题。 @Fabjan,当然,您可以使用 O(NlogN) 订购两者,并且通过一次就可以做到,但这不是 CS 问题。我对数据和数量一无所知。在大多数情况下,提供的解决方案都可以正常工作。 如果我使用或编码,我将进入结果视图错误函数评估已禁用,因为之前的函数评估超时。您必须继续执行才能重新启用函数评估。一个集合有超过 64 000 行,其他大约 60 000 行。 @VladimirToth,只需在谷歌中搜索错误。这里有两个答案。

以上是关于如何比较两个通用集合[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Lodash / javascript:比较两个集合并返回差异[重复]

比较两个数组并返回重复值

java比较两个集合中重复的元素并去除

两个通用 CS 问题 [重复]

C# 判断两个集合(List)是否相等

使用LINQLambda 表达式 委托快速比较两个集合,找出需要新增修改删除的对象