user3659675
user3659675

Reputation: 23

Lambda Expressing Trouble understanding MSDN example

string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

var shortDigits = digits.Where((digit, index) => digit.Length < index);  
foreach (var sD in shortDigits)  
{  
    Console.WriteLine(sD);  
}

MSDN gives the above example of code I understand that "digit" represents one of the strings in the array. What I don't understand is how does the Lambda expression know that the second parameter is the index of the string in the array.

Upvotes: 1

Views: 56

Answers (4)

M.kazem Akhgary
M.kazem Akhgary

Reputation: 19179

how does the Lambda expression know that the second parameter is the index of the string in the array

Lambda expression does not know that. Where extension method knows because the way it was implemented.

Lambda just takes some parameters to do your job. who sends the parameters ? Where extension method as you can see below.

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
    int index = -1;
    foreach (TSource element in source) {
        checked { index++; }

        if (predicate(element, index)) // the element and index is being sent to the function. your function executes here.
             yield return element;
    }
}

The parameters then are given here to run your code

(digit, index) => return digit.Length < index

Upvotes: 1

Fruchtzwerg
Fruchtzwerg

Reputation: 11399

A Lambda expression always consist out of two parts:

  • In front of the lambda operator => are the input parameter(s). In your case, the .Where operation gives a string and an integer called (digit, index).
  • After the lambda operator is the code to return a bool (by working with the two parameters). You could also write it like:

All in all, you can understand the expresison like this function:

bool WhereDigits(string digit, int index)
{
    return digit.Length < index;
}

Means, the function returns true for all digits with a lower length than their arrayindex.

Upvotes: 1

Sweeper
Sweeper

Reputation: 274463

There are two overloads of the Where method. One of them takes a Func<string, bool> and the other takes a Func<string, int, bool>. What you're calling here is obviously the latter.

The Func<string, int, bool> delegate represents a method that takes two parameters (an int and a string) and returns a bool. Your lambda expression has two parameters and returns a bool. Therefore the code compiles.

Now, how does the Where method know the index?

This invovles the inner workings of the Where method. By looking at the reference source, Where calls the WhereIterator method which has all the index logic in it:

int index = -1;
foreach (TSource element in source) {
    checked { index++; }
    if (predicate(element, index)) yield return element;
}

Upvotes: 0

Zein Makki
Zein Makki

Reputation: 30052

Well Simply because this overload is implemented as something like this (dropped generic to make it easier):

static IEnumerable<string> Where(string[] sequence, Func<string, int, bool> predicate)
{
    int index = 0;
    foreach(var item in sequence)
    {
        if (predicate(item, index))
            yield return item;

        index++;
    }
} 

So this implementation sends the index of the item to your lambda expression.

So, you call it like this:

string[] digits = { "zero", "one", "two", "three", "four", 
                    "five", "six", "seven", "eight", "nine" };

var result = Where(digits, PredicateMethod);

The only difference here is that I converted the lambda to an actual method:

static bool PredicateMethod(string digit, int index)
{
    return digit.Length < index;
}

Upvotes: 0

Related Questions