Start learning free

LESSON 115 OF 674 · ARRAYS I

LINQ: Where and Select

Lesson

"Keep the elements that pass a test, then transform the survivors" is one of the most common patterns in all of programming: pick the even numbers and square them, take the finished orders and grab their totals, and so on. You already know how to write it with a loop:

var evenSquares = new List<int>();
foreach (var x in nums) {
    if (x % 2 == 0) {
        evenSquares.Add(x * x);
    }
}

C# ships a second way to say the same thing: LINQ (Language Integrated Query). Two of its methods cover this exact pattern:

  • Where(test) — keeps only the elements for which the test returns true (that's the if)
  • Select(transform) — applies a transformation to every element that got through (that's the x * x)

Lambdas and chaining:

The test and the transform are written as lambdas — tiny inline functions. x => x % 2 == 0 reads as "given x, is x even?". The calls chain left to right, and .ToList() at the end turns the result back into a List<int>:

var evenSquares = nums.Where(x => x % 2 == 0).Select(x => x * x).ToList();

One line — same result as the five-line loop. Good to know: Where and Select are lazy. On their own they only describe the query; nothing actually runs until something enumerates it — and ToList() is what forces that to happen here.


The trap:

Where and Select are not methods of List<int>. They are extension methods that only come into scope while using System.Linq; sits at the top of your file. Delete that line and the compiler acts as if LINQ never existed:

error CS1061: 'List<int>' does not contain a definition for 'Where' and no accessible extension method 'Where' accepting a first argument of type 'List<int>' could be found (are you missing a using directive or an assembly reference?)

Read the part in parentheses — "are you missing a using directive" is the compiler telling you exactly what to fix. In this exercise using System.Linq; is already included for you, but the day you start a file from scratch, this is the error you will meet.


Assignment
Follow the Coding Tutorial and build both versions side by side. Start from var nums = new List<int> { 1, 2, 3, 4, 5, 6 };, then

  • filter the evens and square them with a foreach loop, collecting into loopSquares, and print it,
  • do the same in one line with Where + Select into linqSquares, and print it.

Print each list with string.Join(", ", ...). The exact expected output is:

loop: 4, 16, 36
linq: 4, 16, 36

Hint
The lambda inside Where must produce a bool (x => x % 2 == 0), while the one inside Select produces the new value (x => x * x). Finish the chain with .ToList() so the result is a real list you can print.


STEP 1 OF 8
    Ctrl + Enter to check