Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by and then flatten the items

Tags:

c#

linq

I've got a list of objects with the following properties:

int TownId, int CompanyId, int ProductId, int[] Prices

I want to turn this into a list of TownCompany objects; each item having the following properties:

int TownId, int CompanyId, int[] Products, int[] Prices

So I can do

flatList.GroupBy(l => new { l.TownId, l.CompanyId })

To get a list of groups, which has all the products and prices for each town/company pair. Now, for each key in this lookup, I want to flatten/merge all the values. Seems like I should be able to use SelectMany, but I always get a bit confused by what projections to supply to it...

How do I turn this list of groups into a list of flattened lists for each key? I hope I've made sense.

Example:

If my original list is this:

new[] {
    new Item { TownId = 1, CompanyId = 10, ProductId = 100, Prices = new [] { 1, 2 } },
    new Item { TownId = 1, CompanyId = 10, ProductId = 101, Prices = new [] { 3 } },
};

I want a list that looks like this:

{
    { TownId: 1, CompanyId: 10, Products: [100, 101], Prices: [1, 2, 3] }
}
like image 698
Graham Clark Avatar asked Nov 09 '12 11:11

Graham Clark


2 Answers

If I understood you correctly, then something like this:

flatList.GroupBy(l => new { l.TownId, l.CompanyId })
        .Select(g => new 
        {
            TownId = g.Key.TownId,
            CompanyId = g.Key.CompanyId,   
            Products = g.Select(o => o.ProductId).ToArray(),
            Prices = g.SelectMany(o => o.Prices).ToArray()
        });
like image 42
Mario S Avatar answered Sep 17 '22 21:09

Mario S


You need SelectMany only for Prices; for ProductId it's a simple Select:

flatList
.GroupBy(l => new { l.TownId, l.CompanyId })
.Select(g => new {
    g.Key.TownId
,   g.Key.CompanyId
,   ProductIds = g.Select(o => o.ProductId).ToArray()
,   Prices = g.SelectMany(o => o.Prices).ToArray()
});
like image 131
Sergey Kalinichenko Avatar answered Sep 20 '22 21:09

Sergey Kalinichenko