Reputation: 12367
I want to select elements from myCollection using myFilters for filtering:
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.
However, if myFilters is empty I want to return all the items from 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").
Upvotes: 6
Views: 40479
Reputation: 75326
var result = myCollection
.Where(i => (!myFilters.Any() || myFilters.Contains(i.Name)));
Upvotes: 5
Reputation: 18563
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:
var results = myFilters.Any()
? myCollection.Where(item => myFilters.Contains(item.Name))
: myCollection;
Upvotes: 0
Reputation: 6401
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.
Upvotes: 0
Reputation: 4189
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.
Upvotes: 8
Reputation: 19526
The best you're going to be able to do is project the filters into SomeClass. Something like:
var results = myCollection.Any() ?
myCollection.Where(item => myFilters.Contains(item.Name)) :
myFilters.Select(f => new SomeClass (f));
Upvotes: 2