Вложенный GroupBy в C # - PullRequest
       38

Вложенный GroupBy в C #

0 голосов
/ 20 ноября 2018

Имеющий объект с этой структурой:

public class GroupedObject
{
    public int id { get; set; }
    public string name { get; set; }
    public int value { get; set; }
    public string color { get; set; }
}

Здесь он сгруппирован по одному из своих атрибутов, id.

var myObj = someResponse
    .Select(d => new GroupedObject
    {
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    .GroupBy(o => o.id)
    .ToDictionary(a => a.Key, a => a.Select(o => o).ToList());

Структура:

id - id, name, value, color
id - id, name, value, color
id - id, name, value, color

Я хочу снова сгруппировать его по name, чтобы получить вложенную структуру, подобную этой:

id - name - id, name, value, color
   - name - id, name, value, color
id - name - id, name, value, color
   - name - id, name, value, color 
   - name - id, name, value, color 
   - name - id, name, value, color 
id - name - id, name, value, color
   - name - id, name, value, color 
   - name - id, name, value, color 

Попытка использовать GroupBy дважды неРабота.Ни путем преобразования его в ToList и группировки после этого.

 var myObj = someResponse
        .Select(d => new GroupedObject
        {
            id = d.id,
            name = d.name,
            value = d.value,
            color = d.color
        })
        .GroupBy(o => o.id).GroupBy(o => o.name)
        .ToDictionary(a => a.Key, a => a.Select(o => o).ToList());

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Использование синтаксиса понимания может быть проще:

var myObj = from sr in someResponse
    .Select(d => new GroupedObject
    {
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    group sr by sr.id into g1
    select new {
       ID = g1.Key,
       NamesGroup = from n in g1
                    group n by n.name into g2
                    select new {
                      Name = g2.Key,
                      ...
                    }
    };

Примечание. Если вы скачаете замечательный LINQPad с LINQPad.net, в примерах вы найдете очень хороший вложенный пример группировки с использованием базы данных Northwind.

0 голосов
/ 20 ноября 2018

Вы были на правильном пути, однако вот LINQ для достижения двух вложенных уровней группировки:

someResponse
    .Select(d => new GroupedObject
    { 
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    .GroupBy(o => o.id)
    .ToDictionary(
        a => a.Key,
        a => a.GroupBy(o => o.name).ToDictionary(o => o.Key, o => o));

Это приведет к объекту типа: Dictionary<int, Dictionary<string, IGrouping<string, GroupedObject>>>

Takenчто во внимание, последний тип IGrouping<string, GroupedObject> можно изменить / спроецировать на другой тип, указав подходящую лямду внутри вложенного ToDictionary вызова:

например, изменение вызова на ToDictionary(o => o.Key, o => o.ToList()) приводит к Dictionary<int, Dictionary<string, List<GroupedObject>>>

...