C# 使用 LINQ 过滤列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/417246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filtering lists using LINQ
提问by
I've got a list of People that are returned from an external app and I'm creating an exclusion list in my local app to give me the option of manually removing people from the list.
我有一个从外部应用程序返回的人员列表,我正在本地应用程序中创建一个排除列表,以便我可以选择从列表中手动删除人员。
I have a composite key which I have created that is common to both and I want to find an efficient way of removing people from my List using my List
我创建了一个复合键,它对两者都通用,我想找到一种使用我的列表从我的列表中删除人员的有效方法
e.g
例如
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
I thought LINQ was the ideal way of doing this but after trying joins, extension methods, using yields, etc. I'm still having trouble.
我认为 LINQ 是执行此操作的理想方式,但在尝试了连接、扩展方法、使用收益等之后。我仍然遇到问题。
If this were SQL I would use a not in (?,?,?)
query.
如果这是 SQL,我会使用not in (?,?,?)
查询。
采纳答案by Ryan Lundy
Have a look at the Exceptmethod, which you use like this:
看一下你使用的except方法:
var resultingList =
listOfOriginalItems.Except(listOfItemsToLeaveOut, equalityComparer)
You'll want to use the overload I've linked to, which lets you specify a custom IEqualityComparer. That way you can specify how items match based on your composite key. (If you've already overridden Equals, though, you shouldn't need the IEqualityComparer.)
您将需要使用我链接到的重载,它允许您指定自定义 IEqualityComparer。这样您就可以根据复合键指定项目的匹配方式。(不过,如果您已经覆盖了 Equals,则不需要 IEqualityComparer。)
Edit:Since it appears you're using two different types of classes, here's another way that might be simpler. Assuming a List<Person>
called persons
and a List<Exclusion>
called exclusions
:
编辑:由于您似乎使用了两种不同类型的类,因此这是另一种可能更简单的方法。假设一个List<Person>
被叫persons
和一个List<Exclusion>
被叫exclusions
:
var exclusionKeys =
exclusions.Select(x => x.compositeKey);
var resultingPersons =
persons.Where(x => !exclusionKeys.Contains(x.compositeKey));
In other words: Select from exclusions just the keys, then pick from persons all the Person objects that don'thave any of those keys.
换句话说:从排除项中只选择键,然后从人中选择所有没有这些键的 Person 对象。
回答by Jason Hymanson
I couldn't figure out how to do this in pure MS LINQ, so I wrote my own extension method to do it:
我无法弄清楚如何在纯 MS LINQ 中执行此操作,因此我编写了自己的扩展方法来执行此操作:
public static bool In<T>(this T objToCheck, params T[] values)
{
if (values == null || values.Length == 0)
{
return false; //early out
}
else
{
foreach (T t in values)
{
if (t.Equals(objToCheck))
return true; //RETURN found!
}
return false; //nothing found
}
}
回答by BFree
I would just use the FindAll method on the List class. i.e.:
我只会在 List 类上使用 FindAll 方法。IE:
List<Person> filteredResults =
people.FindAll(p => return !exclusions.Contains(p));
Not sure if the syntax will exactly match your objects, but I think you can see where I'm going with this.
不确定语法是否与您的对象完全匹配,但我认为您可以看到我要做什么。
回答by Fabrizio C.
You can use the "Except" extension method (see http://msdn.microsoft.com/en-us/library/bb337804.aspx)
您可以使用“Except”扩展方法(请参阅http://msdn.microsoft.com/en-us/library/bb337804.aspx)
In your code
在你的代码中
var difference = people.Except(exclusions);
回答by Hath
I would do something like this but i bet there is a simpler way. i think the sql from linqtosql would use a select from person Where NOT EXIST(select from your exclusion list)
我会做这样的事情,但我打赌有一种更简单的方法。我认为 linqtosql 中的 sql 将使用从不存在的人中选择(从排除列表中选择)
static class Program
{
public class Person
{
public string Key { get; set; }
public Person(string key)
{
Key = key;
}
}
public class NotPerson
{
public string Key { get; set; }
public NotPerson(string key)
{
Key = key;
}
}
static void Main()
{
List<Person> persons = new List<Person>()
{
new Person ("1"),
new Person ("2"),
new Person ("3"),
new Person ("4")
};
List<NotPerson> notpersons = new List<NotPerson>()
{
new NotPerson ("3"),
new NotPerson ("4")
};
var filteredResults = from n in persons
where !notpersons.Any(y => n.Key == y.Key)
select n;
foreach (var item in filteredResults)
{
Console.WriteLine(item.Key);
}
}
}
回答by Noah
This LINQ below will generate the SQL for a left outer join and then take all of the results that don't find a match in your exclusion list.
下面的这个 LINQ 将为左外连接生成 SQL,然后获取在排除列表中找不到匹配项的所有结果。
List<Person> filteredResults =from p in people
join e in exclusions on p.compositeKey equals e.compositeKey into temp
from t in temp.DefaultIfEmpty()
where t.compositeKey == null
select p
let me know if it works!
让我知道它是否有效!
回答by Noah
Many thanks for this guys.
非常感谢这些家伙。
I mangaged to get this down to one line:
我设法将其简化为一行:
var results = from p in People
where !(from e in exclusions
select e.CompositeKey).Contains(p.CompositeKey)
select p;
Thanks again everyone.
再次感谢大家。
回答by mucahid kaplan
var result = Data.Where(x =>
{
bool condition = true;
double accord = (double)x[Table.Columns.IndexOf(FiltercomboBox.Text)];
return condition && accord >= double.Parse(FilterLowertextBox.Text) && accord <= double.Parse(FilterUppertextBox.Text);
});
回答by Wes
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
Adapt the list types and lambdas accordingly, and you can filter out anything.
相应地调整列表类型和 lambda,您可以过滤掉任何内容。