如何将下面的代码转换为LINQ。列表有时可以包含20k或30k项。因此,我正在寻找的东西,提高性能和运行速度更快。下面是我的代码:
if(list1 != null)
{
foreach (var item in list1)
{
if(!list2.Any( x => x.Name == item.Name && x.Number == item.Number))
{
list2.Add(item)
}
}
}
我试着使用Parallel.ForEach,但它抛出了一个“集合被修改”错误。
5条答案
按热度按时间pcrecxhr1#
您可以使用LINQ
Distinct
方法。它需要一个IEqualityComparer设置,但幸运的是MSDN示例已经编写了您需要的内容:样本输出:
如果您已经有一些数据,您可以使用
Union
方法,再次使用比较器。注意:我的
RandomLetter()
函数没有做我想要的。但这就足够了。vnjpjtjt2#
20 - 30 k的物品不是那么多。您所需要的只是替换潜在的缓慢线性搜索
具有快速查找数据结构。
最简单的方法是构建一个具有匿名类型的
HashSet
,其中包含Name
和Number
属性。为了做到这一点,您可以使用以下方便的自定义扩展方法:代码会是这样的:
这不是LINQ,但也不需要这样,因为LINQ是用于查询的,而代码是用于修改的。
nwlqm0z13#
您可以将list2设置为ConcurrentBag类型,并如下所示。我不是100%肯定它会像预期的那样工作。
von4xj4u4#
按您的分类分组,从组中选择第一条记录并创建列表。
如果你的
list2
有预先存在的值,你可以这样做…uyto3xhc5#
我最近优化了对不可变项列表的Distinct调用,该列表具有相同的类型用作键-字符串和整数。我重载object.GetHashCode和预先计算的哈希代码,并在构造过程中存储到私有字段中。GetHashCode重载刚刚从该私有成员返回值。
这个修改使得Distinct调用速度可能快了几百倍,因为在内部Distinct迭代器使用了它的内部HashSet实现,该实现对GetHashCode进行了大量调用。
注意:如果重载GetHashCode,您需要重载object.Equals,以便Distinct内部迭代器使用它。
请记住,如果成员在项目对象生存期内可能发生变化,则不能使用这种哈希代码缓存,否则每次有任何字段用作键(即在Equals中使用)的变化。