C# 使用LINQ,如何有条件地选择一些项目,但没有条件选择全部?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12397880/
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
Using LINQ, how to select conditionally some items but when no conditions select all?
提问by Stécy
I want to select elements from myCollection using myFilters for filtering:
我想使用 myFilters 从 myCollection 中选择元素进行过滤:
var myFilters = new List<string> {"111", "222"};
var myCollection = new List<SomeClass> {
new SomeClass ("111"),
new SomeClass ("999")
};
from filter in myFilters
from item in myCollection
where item.Name == filter
select item
would return the "111" item.
将返回“111”项目。
However, if myFilters is empty I want to return all the items from myCollection.
但是,如果 myFilters 为空,我想从 myCollection 返回所有项目。
var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {
new SomeClass ("111"),
new SomeClass ("999")
};
// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter
select item
would return all items ("111" and "999").
将返回所有项目(“111”和“999”)。
采纳答案by devgeezer
If these collections are going to be sizable, then I recommend using a join. It would look something like this:
如果这些集合会很大,那么我建议使用连接。它看起来像这样:
var result =
myFilters.Any() ?
from item in myCollection
join filter in myFilters
on item.Name equals filter into gj
where gj.Any()
select item
: myCollection;
Opportunities for using joins are easily overlooked. This join approach will outperform the contains approach when the lists are remotely large. If they're small and performance is acceptable, then use whichever seems the clearest.
使用连接的机会很容易被忽视。当列表非常大时,这种连接方法将优于包含方法。如果它们很小并且性能可以接受,那么使用看起来最清晰的那个。
回答by itsme86
The best you're going to be able to do is project the filters into SomeClass. Something like:
您将能够做的最好的事情是将过滤器投影到 SomeClass 中。就像是:
var results = myCollection.Any() ?
myCollection.Where(item => myFilters.Contains(item.Name)) :
myFilters.Select(f => new SomeClass (f));
回答by horgh
Try this:
尝试这个:
var result = myCollection.Where(s => !myFilters.Any() ||
myFilters.Contains(s.Name));
//EDIT: commented these lines..based on comment by @Servy
//var result = myCollection.Where(s => myFilters.Count == 0 ||
// myFilters.Contains(s.Name));
Maybe it would be better to count filter collection only once:
也许最好只计算一次过滤器集合:
bool isFilterEmpty = !myFilters.Any();
//bool isFilterEmpty = myFilters.Count == 0; //...or like this
var result = myCollection.Where(s => isFilterEmpty ||
myFilters.Contains(s.Name));
EDIT
编辑
I'd even say that the answer by @itsme86 is correct, but, I guess, he has confused your collections. So his answer should look somehow like this:
我什至会说@itsme86 的答案是正确的,但是,我想,他混淆了您的收藏。所以他的回答应该是这样的:
var results = myFilters.Any()
? myCollection.Where(item => myFilters.Contains(item.Name))
: myCollection;
回答by armen.shimoon
How about this?
这个怎么样?
var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {new SomeClass ("111"), new SomeClass ("999")};
// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter || !myFilters.Any()
select item
Selecting from two collections performs a join based on your where clause. The join condition above says join on item.Name equal to filter OR select it if there are no filters available.
从两个集合中选择执行基于您的 where 子句的连接。上面的连接条件表示 item.Name 上的 join 等于过滤器或在没有可用过滤器时选择它。
回答by cuongle
var result = myCollection
.Where(i => (!myFilters.Any() || myFilters.Contains(i.Name)));

