Bodhi
Bodhi

Reputation: 354

How does group by 'x' work?

I recently came across the following piece of Code

from item in collection
group item by 'x' into itemGroup
select new
{
    Amount = itemGroup.Sum(z => z.Amount),
    PrevAmount = itemGroup.Sum(x => x.PrevAmount)
}

Normally we group by an attribute of a collection like "group by item.Type". But in the above case what will be the result? Will it be one single record, or will each record will be in one group?

Upvotes: 1

Views: 1463

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

It's more easy to see what's happening if you'll take a look on your query written in method syntax (actually all query syntax queries are compiled into method syntax queries). So, your query is same as

collection.GroupBy(item => 'x')

and some projection (Select operator), which does not matter here. So, what is item => 'x'? Its a group key selector. I.e. you pass each item to this anonymous method and it calculates key. This key is used to determine to which group current item should go. Usually you should calculate key based on values of item. Like item => item.Type but in this case you just return constant value. So, for all items calculated key value will be same. And you will have single grouping with key 'x' and all item in this group.

Upvotes: 1

George Mamaladze
George Mamaladze

Reputation: 7931

Assume your collection contains following objects:

{x=1; z=10}
{x=1; z=20}
{x=2; z=30}
{x=3; z=40}
{x=3; z=50}

after executing group by you will get an enumeration of 3 items.

Each item (having type IGrouping<T>) is an enumerable itself like this:

[{x=1; z=10}, {x=1; z=20}]
[{x=2; z=30}]
[{x=3; z=40}, {x=3; z=50}]

After that for each element of this enumeration you are creating a new object (the line with select new) containing a sum of 'x'-es and 'z'-s of each sub item in a group.

[{x=1; z=10}, {x=1; z=20}]           -> {Amount=10+20; PrevAmount=1+1}
[{x=2; z=30}]                        -> {Amount=30; PrevAmount=2}
[{x=3; z=40}, {x=3; z=50}]           -> {Amount=40+50; PrevAmount=3+3}

So your result is:

{Amount=30; PrevAmount=2}
{Amount=30; PrevAmount=2}
{Amount=90; PrevAmount=6}

That's my understanding how your code will work.

Upvotes: 2

Related Questions