Using LINQ, how to conditionally select some elements, but when no condition selects everything?

I want to select elements from myCollection using myFilters to filter:

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 

will return the element "111".

However, if myFilters is empty, I want to return all the elements from myCollection.

 var myFilters = new List<string> (); var myCollection = new List<SomeClass> { new SomeClass ("111"), new SomeClass ("999") }; // Here where I'm lost... from filter in myFilters from item in myCollection where item.Name == filter select item 

will return all elements ("111" and "999").

+4
source share
5 answers

If these collections are significant, I recommend using a mix. It will 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 associations are easily overlooked. This join approach will be superior to the addition approach when lists are remotely large. If they are small and performance is acceptable, use what seems most clear.

+7
source
 var result = myCollection .Where(i => (!myFilters.Any() || myFilters.Contains(i.Name))); 
+3
source

The best you can do is project filters in SomeClass. Sort of:

 var results = myCollection.Any() ? myCollection.Where(item => myFilters.Contains(item.Name)) : myFilters.Select(f => new SomeClass (f)); 
+1
source

Try the following:

 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)); 

Perhaps it would be better to count the 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 would even say that the answer by @ itsme86 is correct, but I think it confused your collections. Therefore, his answer should look something like this:

 var results = myFilters.Any() ? myCollection.Where(item => myFilters.Contains(item.Name)) : myCollection; 
0
source

How about this?

 var myFilters = new List<string> (); var myCollection = new List<SomeClass> {new SomeClass ("111"), new SomeClass ("999")}; // Here where I'm lost... from filter in myFilters from item in myCollection where item.Name == filter || !myFilters.Any() select item 

The choice of the two collections performs the union based on your where clause. The join condition above indicates joining an element. The name is equal to the filter OR select it if there are no filters available.

0
source

Source: https://habr.com/ru/post/1433917/


All Articles