157

The Select and Where methods are available in Linq. What should every developer know about these two methods? For example: when to use one over the other, any advantages of using one over the other, etc.

Pooven
  • 1,744
  • 1
  • 25
  • 44
SBurris
  • 7,378
  • 5
  • 28
  • 36
  • 7
    I don't think this question should be marked as CW, it could possibly have a definitive answer. – Brandon Jul 31 '09 at 14:14
  • 1
    @Brandon there's nothing wrong with marking something CW if it is objective. – Rex M Jul 31 '09 at 14:18
  • @Rex, I agree. Just saying that the difference between Select and Where has a definitive answer, and the second part of the question would likely be based off commonly accepted practices. I was just pointing it out in case the OP was unsure about marking things as CW. If he did intend for it to be CW, then thas fine by me. – Brandon Jul 31 '09 at 14:21
  • 6
    There is plenty wrong with it. CW is useless, and getting more so when people mark questions completely at random as CW – jalf Jul 31 '09 at 14:21

8 Answers8

161

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

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 23
    `Select` will always return the same number of elements in the list (regardless of a filter condition you may have). `Where` can return less elements depending on your filter condition. – goku_da_master Nov 17 '14 at 17:01
  • And [here](https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx) is an MSDN example of `select` and [here](https://msdn.microsoft.com/en-us/library/bb534803(v=vs.110).aspx) is one for `where` – yazanpro Oct 12 '16 at 16:19
  • 2
    At least for me, having some background with other languages, it helps to think that ``Where == filter`` and ``Select == map`` – bgusach Nov 11 '16 at 09:34
62

They are distinct:

Select is all about transformation.

Where is all about filtering.

bruno conde
  • 47,767
  • 15
  • 98
  • 117
56

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!

Bruno Reis
  • 37,201
  • 11
  • 119
  • 156
27

Where ~= Filter

Select ~= Map

Both returns IEnumerable<T>

Downhillski
  • 2,555
  • 2
  • 27
  • 39
20

Select maps an enumerable to a new structure. If you perform a select on an IEnumerable, you will get an array with the same number of elements, but a different type depending on the mapping you specified. Where filters the IEnumerable so that it gives you a subset of the original IEnumerable.

Steve
  • 11,763
  • 15
  • 70
  • 103
8

If you know how they have implemented Where and select extension methods you can predict what it is doing... I tried to implement where and select extension methods... You can have a look at it...

Where Implementation ::

public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{

    foreach ( var data in a )
    {
        //If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
        if ( Method.Invoke ( data ) )
        {
            yield return data;
        }
    }
}

Select implementation ::

public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<TSource> a , Func<TSource , TResult> Method )
{
    foreach ( var item in a )
    {
        //Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
        yield return Method.Invoke ( item );
    }
}

My implementation works fine for any collection... But it differs from Microsoft implemented Extension methods, Because they use expression trees to implement the same.

5
List<string> randomList = new List<string> { "1", "2", "3" };        
var result = test.Where(value => value == "1");
Console.WriteLine(result.Count());

Will produce "1" as result, the one that contains the object "1" after filtering out.

List<string> randomList = new List<string> { "1", "2", "3" };        
var result = test.Select(value => value == "1");
Console.WriteLine(result.Count());

Will produce "3" as result, as it doesn't filter, even if the condition match up.

Conclusion: Where checks conditions. Select doesn't care a s*** about conditions, it will map everything, but the point is, it will map only what you want to map exactly... (by map, it means, to read, if you prefer). For instance, in an class with multiple variables, the select operation will allow you to choose which one you want to read:

class Person
{
     public string Name { get;set; }
     public int Age { get;set; }       
}

and then you can have:

List<Person> persons = new();
List<string> namePersons = persons.Select(person => person.Name);

Which allow you to map only the Name of each person if your list.

Select can implement the functionality also of 'let' operation (Code equivalent to the 'let' keyword in chained LINQ extension method calls)

And you can use it also for creating new objects, with the variables you want to use in the list you read:

  List<Person> persons = new();
  var personsWithBlueEyes = persons.Select(person => new { Name=person.Name, Eyes="blue" });

You have to wonder:

  1. What on earth I need to map from all of these values I have?
  2. What conditions I have to apply to filter only the values I need to (if needed indeed)?

Hope this shed light

Andrés Fg
  • 138
  • 1
  • 7
2

In case of Select it you can map to an IEnumerable of a new structure.

  A.Select(x=>new X{UID=x.uid, UNAME=x.uname}) 
  //input as [IEnumerable<A>] -------->  return output as [IEnumerable<X> ]

Where() works as an filter to the IEnumerable, it will return the result on the basis of the where clause.

A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] -------->  return output as [IEnumerable<A> ]