Reputation: 23
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
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
Reputation: 11399
A Lambda expression always consist out of two parts:
=>
are the input parameter(s). In your case, the .Where
operation gives a string and an integer called (digit, index)
.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
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
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