Linq - 排除不同列表类型中的项目

问题描述 投票:0回答:4

有没有办法选择列表中不包含在另一个列表中的项目?例如:

list1 = From t In list1 Where Not list2.Contains(t.column1)

这给了我错误:

Value of type 'Integer' cannot be converted to '<anonymous type>'

这是有道理的,因为 list2.Contains 期望与 list2 具有相同的类型。但是,列表类型不同。我只想根据列比较进行选择。

vb.net linq
4个回答
7
投票

那么

list2
实际上包含什么?如果您可以精确地表达您的查询,我们或许可以用 LINQ 表达它。如果不知道
list1
list2
column1
是什么,就很难提供帮助。

想说的是List<T>.Contains

对于你检查的每个项目来说都是O(n)。如果 
list2
 可能不小,您可能很想创建一个 
HashSet<T>
 - 那么每个 
Contains
 调用都会快很多。

但是话又说回来,当我们更多地了解情况时,我们很可能会提出完全不同的解决方案。请尽可能具体地提出问题,以获得最佳答案。

编辑:如果 tvanfosson 的解决方案适合您

并且如果您使用 LINQ to Objects,那么您就会遇到潜在的性能问题。最好(IMO)在 list2

 
once 上进行投影并构建一组:

Dim invalid = New HashSet(Of Integer)(list2.Select(Function(x) x.Id)) list1 = From t in list1 Where Not invalid.Contains(t.column1)
    

7
投票
看.

Except()

扩展方法,结合投影:

list1 = list1.Except(list2.Select(Function(l) l.ID))
    

6
投票
你尝试过这样的事情吗?

list1 = From t In list1 Where Not list2.Any(l => t.column1 = l.column1 AndAlso t.column2 = l.column2)

我不确定它的效率如何,但我认为它应该对你有用。


0
投票
我创建了这个扩展方法: 请注意,第二个序列可以具有不同的类型,但是您必须指定键和可选的比较器。

public static IEnumerable<TOuter> Except<TOuter, TInner, TKey>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, IEqualityComparer<TKey> comparer) { IEnumerable<TOuter> iguales = outer.Join( inner : inner, outerKeySelector: tOuter => outerKeySelector(tOuter), innerKeySelector: tInner => innerKeySelector(tInner), resultSelector : (o, _) => o, comparer : comparer); return outer.Except(iguales); }
以下是如何使用它

String name = "John"; Char[] chars = { 'h', 'n' }; var result = name.Except( inner : chars, outerKeySelector: c => c, innerKeySelector: c => c); // result will contain J, o
    
© www.soinside.com 2019 - 2024. All rights reserved.