Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do lambda parameters map in TakeWhile?

Tags:

c#

lambda

linq

I'm learning LINQ using the 101 LINQ Samples in the MSDN page and I came across this code:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

foreach (var n in firstSmallNumbers)
{
    Console.WriteLine(n);
}

The purpose of this function is to "use TakeWhile to return elements starting from the beginning of the array until a number is hit that is less than its position in the array."

How exactly the n and index know which parameter to take? (i.e. how does n know it will take 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 and how does index know it will do an increment of 0, 1, 2, 3...)?

like image 601
C.J. Avatar asked Oct 31 '14 20:10

C.J.


People also ask

How to use lambda expressions in c#?

To create a lambda expression, you specify input parameters (if any) on the left side of the lambda operator and an expression or a statement block on the other side. When you use method-based syntax to call the Enumerable. Select method in the System. Linq.

Why do we use lambda expression in C#?

Lambda expressions in C# are used like anonymous functions, with the difference that in Lambda expressions you don't need to specify the type of the value that you input thus making it more flexible to use. The '=>' is the lambda operator which is used in all lambda expressions.

What is lambda expression in Linq?

Advertisements. The term 'Lambda expression' has derived its name from 'lambda' calculus which in turn is a mathematical notation applied for defining functions. Lambda expressions as a LINQ equation's executable part translate logic in a way at run time so it can pass on to the data source conveniently.


3 Answers

Because the overload is defined that way. From MSDN

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate
)

The predicate argument is described as follows:

A function to test each source element for a condition; the second parameter of the function represents the index of the source element.

The TSource argument is the item, and the int is the index. The bool is the return value.

When you write (n, index) => ... the n takes the first parameter (TSource) and index takes the second (int).

like image 75
BradleyDotNET Avatar answered Oct 23 '22 12:10

BradleyDotNET


In a lambda expression, everything before => are parameters to the method. As an example, the (n, index) => n >= index lambda expression can be rewritten as a method similar to this:

public bool CheckIfValueIsGreaterOrEqualToIndex(int value, int index)
{
    if(value >= index)
    {
         return true;
    }
    else
    {
        return false;
    }
}

So, using that method, you can specify whatever name you want to the parameters (in this instance I used value instead of n). And instead of the lambda you could use that method here:

numbers.TakeWhile(CheckIfValueIsGreaterOrEqualToIndex);
like image 38
Dave Zych Avatar answered Oct 23 '22 13:10

Dave Zych


The first parameter n is associated with the number on numbers and the second the index is associated with the index of the number in the sequence. Actually, it doesn't matter if you name them n and index, you could name whatever. In any case the first parameter would be associated with the random item in the sequence and and the second parameter with the index of this sequence.

As more formally Bradley stated above the definition of TakeWhile is the following:

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate
)

As we see from the above the TakeWhile is an extension method defined on types that implements the IEnumerable interface. Note now two things, the parameters that takes as input this method and it's return type.

It return a sequence of objects of the type of the objects that are in the supplied sequence.

What it takes as a parameter?

A predicate. A predicate is a method that takes some parameters and returns either true or false. What are the parameters of the predicate?

The parameters of the predicate are a TSource element, and an int. The TSource element would be the random element of your sequence the int would be the index of this element.

What is this (n, index) => n >= index now?

This is a lambda expression, which acts like a predicate.

Specifficaly, given the variables called n and index, returns true if n>=index, otherwise returns false. Supplying this expression to the TakeWhile extension method is like passing there a Func<TSource, int, bool> predicate. So you get what you want.

like image 35
Christos Avatar answered Oct 23 '22 13:10

Christos