I have a LINQ query where I'm filtering a list using where multiple WHERE statements.
string[] filters = new string[]{"a","b","c","d"};
var filtered = from n in bigList where n != "a" where n != "b" where n != "c" where n != "c" select n;
How do I use the filters array instead of having to write multiple where clauses?
CodePudding user response:
This is the answer, An array filtered by another array.
var filtered = bigList.Where(d => !filters.Contains(d));
CodePudding user response:
Consider that HashSet.Contains
is an O(1)
operation, whereas Array.Contains
is an O(n)
operation.
Granted, if you only have 1-2 (maybe 3) values in the array and if the hashing algo or string data is particularly slow then Array.Contains might be faster, but consider that if you only have 1-3 elements then just use individual locals instead of an array because that will be even faster (as it will effectively be an unrolled-loop)
HashSet<String> filterValueSet;
{
String[] filterValues = new String[]
{
"a", "b", "c", "d"
};
filterValueSet = new HashSet<String>( filterValues ); // Pass `StringComparer.OrdinalIgnoreCase` as the second argument for case-insensitive matching.
}
IReadOnlyList<String> filtered = bigList
.Where( v => !filterValueSet.Contains( v ) )
.ToList();
Using a HashSet<String>
like this is the fastest way to filter a set of values.
If the above code looks intimidating, it can be reduced down to just this, though:
HashSet<String> filterValueSet = new [] { "a", "b", "c", "d" }.ToHashSet();
IReadOnlyList<String> filtered = bigList
.Where( v => !filterValueSet.Contains( v ) )
.ToList();