Question

I have a List<String> myList.

I want to take the first 10 items in this list that match some criteria (let's say .Contains("a"), for example).

I have:

Var results = myList.Where(o=>o.Contains("a")).Take(10);

Which works fine, but has LINQ performed a Where to retrieve all of the items meeting this criteria and then only took the first 10 of those? Or will this be compiled in a way that the entire LINQ statement is taken into consideration (i.e. it will perform the Where but only up until it reaches 10 items)?

Was it helpful?

Solution

LINQ uses lazy evaluation. When you do the following line:

var results = myList.Where(o=>o.Contains("a")).Take(10);

Nothing happens. Only the query is built. When you enumerate results, (e.g. with a foreach or a ToList()) then the Where and Take will be applied to myList: Where will be executed, as needed, until up to 10 true values are found.

OTHER TIPS

The Where statement returns an IEnumerable, which is waiting to be enumerated. The execution of the Where logic is delayed until you 'ask' the IEnumerable for its next value.

The Take(10) statement does just that - asks it for its 'next match' for the Where condition. This will execute 10 times, then finish. But of course, for the same reason, the logic of the Take(10) statement is not actually executed until you enumerate through the final returned value (results, in your case).

So yes, it's kind of optimized, but probably not quite in the way you imagined.

Look at the code below:

using System;
using System.Collections.Generic;
using System.Linq;

public class Test {
    public static void Main(String[] args) {
        var l = new List<String>() { "a", "ab", "b", "bb", "bc", "ba", "c", "ca", "cc" };

        foreach (var s in l.Where(e => { Console.WriteLine(e); return e.Contains("a"); }).Take(3)) {
            Console.WriteLine("loop: {0}", s);
        }
    }
}

The output is:

a
loop: a
ab
loop: ab
b
bb
bc
ba
loop: ba

So as you can see it is optimized (the strings after "c" are not evaluated).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top