Confused about the lamda expression

  • Thread starter Thread starter gnewsgroup
  • Start date Start date
G

gnewsgroup

I want to get my hands dirty with Linq, so I watched a few videos from
www.asp.net, and then turned to

http://msdn2.microsoft.com/en-us/library/bb397687.aspx

for some introduction about the new lamda feature of C#.

In the article linked above, there is an example reproduced here:

int[] numbers = {5,4,1,3,9,8,6,7,2,0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

I gave it a test, and oddNumbers has a value of 5.

I am confused by the 2nd line, i.e.,

int oddNumbers = numbers.Count(n => n % 2 == 1);

The Count method, as the MSDN doc says, returns the number of elements
in a sequence. So, does

n => n % 2 == 1

return a sequence? How does this happen?

Please shed some light. Thank you.
 
OK;

"n => n % 2 == 1"
expresses a predicate; for any "n" passed in, it returns true if-and-
only-if the argument is odd.


* numbers is an int[], so implements IEnumerable<int>
* the compiler (with "using System.Linq") locates an extension method:
public static int Count<TSource>(this IEnumerable<TSource>
source, Func<TSource, bool> predicate);

the first "this" arg is automatically numbers; the second is a
predicate - i.e. a test to apply to each element in turn.

Internally, Count is probably something like (with a few null-arg
checks):

int count = 0;
foreach (TSource item in source)
{
if (predicate(item)) count++;
}
return count;

i.e. it simply walks the list and checks each item.

The C# compiler can convert a lambda to either a delegate or an
expression. In this case, it is compiling to a delegate to pass as the
second argument to Count.

Does that make sense?

Marc
 
gnewsgroup said:
I want to get my hands dirty with Linq, so I watched a few videos from
www.asp.net, and then turned to

http://msdn2.microsoft.com/en-us/library/bb397687.aspx

for some introduction about the new lamda feature of C#.

In the article linked above, there is an example reproduced here:

int[] numbers = {5,4,1,3,9,8,6,7,2,0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

I gave it a test, and oddNumbers has a value of 5.

I am confused by the 2nd line, i.e.,

int oddNumbers = numbers.Count(n => n % 2 == 1);

The Count method, as the MSDN doc says, returns the number of elements
in a sequence. So, does

n => n % 2 == 1

return a sequence? How does this happen?

No - "numbers" is the sequence. It's an array, implementing
IEnumerable<int>.

If you just call numbers.Count() you'll get 10. The version with the
lambda expression is saying "only count elements which match this
predicate".

It's sort of similar to calling:

numbers.Where(n => n % 2 == 1)
.Count()

That may help, or it may confuse you more, of course...
 
gnewsgroup said:
I want to get my hands dirty with Linq, so I watched a few videos from
www.asp.net, and then turned to

http://msdn2.microsoft.com/en-us/library/bb397687.aspx

for some introduction about the new lamda feature of C#.

In the article linked above, there is an example reproduced here:

int[] numbers = {5,4,1,3,9,8,6,7,2,0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

I gave it a test, and oddNumbers has a value of 5.

I am confused by the 2nd line, i.e.,

int oddNumbers = numbers.Count(n => n % 2 == 1);

The Count method, as the MSDN doc says, returns the number of elements
in a sequence. So, does

n => n % 2 == 1

return a sequence? How does this happen?

Please shed some light. Thank you.
 
int[] numbers = {5,4,1,3,9,8,6,7,2,0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

I gave it a test, and oddNumbers has a value of 5.

I am confused by the 2nd line, i.e.,

int oddNumbers = numbers.Count(n => n % 2 == 1);

The Count method, as the MSDN doc says, returns the number of elements
in a sequence. So, does

n => n % 2 == 1

return a sequence? How does this happen?

No, it returns true or false depending on whether the number is odd.

A lambda expression is a way of creating a function without giving it a
name. Suppose you defined:

bool blah(n) { return n%2 == 1; }

That's a function named blah.

(n => n%2 == 1)

is the same function without a name.

The Count method takes a function that tells it which elements to count.
I'm not sure if

numbers.Count(blah)

is valid syntax, but it ought to be; it means "count the ones that return
'true' when given as the argument of 'blah'".

numbers.Count(n => n%2 == 1)

is the same thing without defining it separately giving it a name.

Lambda expressions are the stuff of which Lisp is made. They are a basic
tool of advanced, abstract computer programming.
 
OK;

"n => n % 2 == 1"
expresses a predicate; for any "n" passed in, it returns true if-and-
only-if the argument is odd.

* numbers is an int[], so implements IEnumerable<int>
* the compiler (with "using System.Linq") locates an extension method:
public static int Count<TSource>(this IEnumerable<TSource>
source, Func<TSource, bool> predicate);

the first "this" arg is automatically numbers; the second is a
predicate - i.e. a test to apply to each element in turn.

Internally, Count is probably something like (with a few null-arg
checks):

int count = 0;
foreach (TSource item in source)
{
if (predicate(item)) count++;
}
return count;

i.e. it simply walks the list and checks each item.

The C# compiler can convert a lambda to either a delegate or an
expression. In this case, it is compiling to a delegate to pass as the
second argument to Count.

Does that make sense?

Marc

OK, thank you very much for the light you shed, and I think it's very
helpful.

It seems that 2 things are essential here. One is that this Count
method is an extension method, which is also new from 3.0. The other
is that this Count method may be implemented with a for loop like what
you have above.

Once we get these 2 points, it seems that the MSDN example is
understandable now.
 
int[] numbers = {5,4,1,3,9,8,6,7,2,0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
I gave it a test, and oddNumbers has a value of 5.
I am confused by the 2nd line, i.e.,
int oddNumbers = numbers.Count(n => n % 2 == 1);
The Count method, as the MSDN doc says, returns the number of elements
in a sequence. So, does
n => n % 2 == 1
return a sequence? How does this happen?

No, it returns true or false depending on whether the number is odd.

A lambda expression is a way of creating a function without giving it a
name. Suppose you defined:

bool blah(n) { return n%2 == 1; }

That's a function named blah.

(n => n%2 == 1)

is the same function without a name.

The Count method takes a function that tells it which elements to count.
I'm not sure if

numbers.Count(blah)

is valid syntax, but it ought to be; it means "count the ones that return
'true' when given as the argument of 'blah'".

numbers.Count(n => n%2 == 1)

is the same thing without defining it separately giving it a name.

Lambda expressions are the stuff of which Lisp is made. They are a basic
tool of advanced, abstract computer programming.

Thank you very much. I used to do python, which also uses lamda
expression. So I know it a little bit.

I think, for this particular question/confusion I have, it is
important to understand that this Count method maybe is like what Marc
Gravell has shown. In any case, it's important to assume that some
iteration is done in this Count method, otherwise, it is hard to
understand this example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top