How to return two arrays using one WHERE statement

Is it possible to combine these two operators into one that returns the results "contains" and "does not contain"?

string[] words = { "one", "two", "three", "four" }; int[] numbers = { 4, 5, 6 }; string[] contains = (from w in words where numbers.Contains(w.Length) select w).ToArray(); string[] notContains = (from w in words where !numbers.Contains(w.Length) select w).ToArray(); 
+5
source share
2 answers

You can do:

 var groups = words.GroupBy(w => numbers.Contains(w.Length)); 

This will return no more than two groups: one with the false key and one with the true key.

Edit

As noted in the vc 74 comments, numbers.Contains is an O (n) operation when numbers is an array. Converting it to a HashSet instead will make it a constant time operation, which is asymptotically much faster.

So here is the updated code:

 var numberHS = new HashSet<int>(numbers); var groups = words.GroupBy(w => numberHS.Contains(w.Length)); 
+8
source

You can also use ToLookup :

 var containsLengthLookup = words.ToLookup(w => numbers.Contains(w.Length)); string[] contains = containsLengthLookup[true].ToArray(); string[] notContains = containsLengthLookup[false].ToArray(); 

If one of them is empty (or the original array is empty), you get an empty string[] .

There is one difference from GroupBy , the search is cached. Therefore, it is more effective if you use it several times, but the information is just a snapshot. If you change words or numbers , this is not reflected in the search.

+6
source

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


All Articles