4

I just found this lambda expression:

myCustomerList.GroupBy(cust => cust.CustomerId).Select(grp => grp.First());

Correct me if I am wrong, but with this lambda you can distinct the myCustomerList on the CustomerId and that's exaclty what I need. But I am trying to figure out how it works.

The first step is the groupby: this result in a dictionary, IGouping<long, Customer> with the CustomerId as the key of the dictionary.

Second a select takes place and this is the part I don't get. The select selects a customer, but how can it select a Customer from a dictionary? You need a key for this, because of the group by. Where's that key? And how is First() helping here?

Can you tell me in detail how the last part works?

1

2 Answers 2

4

It's not selecting it from the dictionary - it's saying for each grouping in the result of GroupBy, select the first entry. Note that IGrouping<TKey, TElement> implements IEnumerable<TElement>.

Basically a group has two things:

  • A key
  • A list of elements

This is selecting the first element from each group.

Sign up to request clarification or add additional context in comments.

6 Comments

But what happens then in the background. When I see this it suggests - in my opinion - that a dictionary is made (which implements IEnumerable). And when that dictionary is created, the select is executed. But this is not the case?
@Martijn: No, that's not the case. The grouping still isn't evaluated until something tries to read from it - although at that point the input sequence is completely consumed. It's probably best to just point you at my Edulinq blog post for GroupBy: msmvps.com/blogs/jon_skeet/archive/2011/01/01/…
I still don't get it completely. The groupBy isn't executec when the select takes place? But when is it executed? Since the First() method does select the first object of each group.
@Martijn: If you don't use the results of the Select(), nothing's going to ask that for its first element - which means it's not going to ask the grouping for its first element. You need to read up on deferred execution: msmvps.com/blogs/jon_skeet/archive/2010/09/03/… gives some of the details.
I see, when (for example) ToList() is called at the end, everything gets executed. And when it is executed, I come back to my first comment, what happens? A dictionary is created (which implements IEnumerable) and based on this result, the select is executed with the First() method? And if this is the case, what is the value of the 'Key` property for the dictionary?
|
3

Lets says your collection is:

{Name=a, CustomerId=1}
{Name=a, CustomerId=1}
{Name=b, CustomerId=2}
{Name=b, CustomerId=2}

After group by it becomes

{ key = 1, Values = {Name=a, CustomerId=1}, {Name=a, CustomerId=1} }
{ key = 2, Values = {Name=a, CustomerId=2}, {Name=a, CustomerId=2} }

After last select (i.e select first from the Values in the above notation it becomes:

{Name=a, CustomerId=1}
{Name=a, CustomerId=2}

Hence it is distinct customer based on the ID.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.