Where
finds items that match and only returns those that do (filtering).
-> IEnumerable<A>
in, IEnumerable<A>
out
Select
returns something for all items in the source (projection / transformation). That something might be the items themselves, but are more usually a projection of some sort.
-> IEnumerable<A>
in, IEnumerable<B>
out
They are distinct:
Select
is all about transformation.
Where
is all about filtering.
Select and Where are two completely different operators acting on IEnumerables.
The first one is what we call a Projection Operator, while the last one is a Restriction Operator.
One interesting way to have insight on the behavior of such operators is to take a look at their "functional type".
Select : (IEnumerable<T1>, Func<T1,T2>) → IEnumerable<T2>; it takes as input both an IEnumerable containing elements of type T1 and a function transforming elements of type T1 into elements of type T2. The output is an IEnumerable containing elements of type T2.
From this, one can easily guess that this operator will produce its output by applying the input function on each element of the input IEnumerable, and wrapping the results inside a new IEnumerable.
Using some math-like notation, it takes as input (a, b, c, ...) : IEnumerable<T1> and f : T1 → T2 and produces (f(a), f(b), f(c), ...) : IEnumerable<T2>
Where : (IEnumerable<T1>, Func<T1, bool>) → IEnumerable<T1> ; this one takes an IEnumerable containing elements of type T1 and a predicate on T1 (that is, a function that produces a boolean result for an input of type T1). You see that the output is also an IEnumerable containing elements of type T1.
This time one would guess that an element of the input IEnumerable will be present on the output IEnumerable depending on the result of the application of the predicate to the element. Adding to this the semantics of the operator name, you can be sure that it will produce the output IEnumerable by taking from the input one only those elements that evaluates to true on the application of the predicate.
People with functional programming background usually think like this. It allows you to deduce (or at least guess...) what an operator does only by looking at it's type!
As an exercise, try to look at other operators introduced by LINQ on IEnumerables and deduce their behavior, before looking at the documentation!
Where
~= Filter
Select
~= Map
Both returns IEnumerable<T>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With