有没有办法选择列表中不包含在另一个列表中的项目?例如:
list1 = From t In list1 Where Not list2.Contains(t.column1)
这给了我错误:
Value of type 'Integer' cannot be converted to '<anonymous type>'
这是有道理的,因为 list2.Contains 期望与 list2 具有相同的类型。但是,列表类型不同。我只想根据列比较进行选择。
那么
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)
Except()
扩展方法,结合投影:
list1 = list1.Except(list2.Select(Function(l) l.ID))
list1 = From t In list1 Where Not list2.Any(l => t.column1 = l.column1 AndAlso t.column2 = l.column2)
我不确定它的效率如何,但我认为它应该对你有用。
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