Search code examples
linq

LINQ: Use an Array for the where filter


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?


Solution

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