如何比较两个通用集合[重复]
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));
【问题讨论】:
可能是一个 LINQIntersect
?
看看这个答案,可能会有帮助***.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<>.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,只需在谷歌中搜索错误。这里有两个答案。以上是关于如何比较两个通用集合[重复]的主要内容,如果未能解决你的问题,请参考以下文章