使用LINQ过滤列表

20 c# linq linq-to-objects list

我有一个从外部应用程序返回的人员列表,我在我的本地应用程序中创建了一个排除列表,让我可以选择从列表中手动删除人员.

我有一个我创建的复合键,这两个键都很常见,我希望找到一种有效的方法,可以使用我的列表从列表中删除人员

例如

class Person
{
    prop string compositeKey { get; set; }
}

class Exclusions
{
    prop string compositeKey { get; set; }
}

List<Person> people = GetFromDB;

List<Exclusions> exclusions = GetFromOtherDB;

List<Person> filteredResults = People - exclustions using the composite key as a comparer
Run Code Online (Sandbox Code Playgroud)

我认为LINQ是这样做的理想方式,但是在尝试连接,扩展方法,使用产量等之后我还是遇到了麻烦.

如果这是SQL我会使用not in (?,?,?)查询.

Rya*_*ndy 33

看一下Except方法,你可以这样使用:

var resultingList = 
    listOfOriginalItems.Except(listOfItemsToLeaveOut, equalityComparer)
Run Code Online (Sandbox Code Playgroud)

您将要使用我链接的重载,它允许您指定自定义IEqualityComparer.这样,您可以根据组合键指定项目的匹配方式.(但是,如果已经重写了Equals,则不应该使用IEqualityComparer.)

编辑: 因为看起来你正在使用两种不同类型的类,这是另一种可能更简单的方法.假设有一个List<Person>被叫personsList<Exclusion>被叫exclusions:

var exclusionKeys = 
        exclusions.Select(x => x.compositeKey);
var resultingPersons = 
        persons.Where(x => !exclusionKeys.Contains(x.compositeKey));
Run Code Online (Sandbox Code Playgroud)

换句话说:只从键中选择排除项,然后从人员中选择所有没有任何键的Person对象.


Wes*_*Wes 6

var thisList = new List<string>{ "a", "b", "c" };
var otherList = new List<string> {"a", "b"};

var theOnesThatDontMatch = thisList
        .Where(item=> otherList.All(otherItem=> item != otherItem))
        .ToList();

var theOnesThatDoMatch = thisList
        .Where(item=> otherList.Any(otherItem=> item == otherItem))
        .ToList();

Console.WriteLine("don't match: {0}", string.Join(",", theOnesThatDontMatch));
Console.WriteLine("do match: {0}", string.Join(",", theOnesThatDoMatch));

//Output:
//don't match: c
//do match: a,b
Run Code Online (Sandbox Code Playgroud)

相应地调整列表类型和 lambda,您就可以过滤掉任何内容。

https://dotnetfiddle.net/6bMCvN


BFr*_*ree 5

我只会在List类上使用FindAll方法。即:

List<Person> filteredResults = 
    people.FindAll(p => return !exclusions.Contains(p));
Run Code Online (Sandbox Code Playgroud)

不知道语法是否会与您的对象完全匹配,但是我想您可以看到我要使用的语法。


小智 5

非常感谢这些家伙。

我设法将其简化为一行:

  var results = from p in People 
                where !(from e in exclusions 
                        select e.CompositeKey).Contains(p.CompositeKey) 
                select p;
Run Code Online (Sandbox Code Playgroud)

再次感谢大家。