Подтвердить что ты не робот

Как создать вложенный групповой словарь с помощью LINQ?

Как создать вложенную группировку для таблицы ниже, используя LINQ? Я хочу группировать Code, затем Mktcode.

Code Mktcode Id
==== ======= ====
1    10      0001 
2    20      0010 
1    10      0012 
1    20      0010 
1    20      0014 
2    20      0001
2    30      0002
1    30      0002
1    30      0005

Мне нужен словарь, в конце концов, вроде

Dictionary<Code, List<Dictionary<Mktcode, List<Id>>>>

Значения этого словаря будут

{1, ({10,(0001,0012)}, {20,(0010,0014)}, {30, (0002, 0005)})},
{2, ({20,(0001, 0010)}, {30, (0020)} )}
4b9b3361

Ответ 1

Я бы подумал об этом так:

  • В первую очередь вы группируетесь по коду, так что сделайте это первым
  • Для каждой группы у вас есть список результатов, поэтому примените другую группу.

Что-то вроде:

var groupedByCode = source.GroupBy(x => x.Code);

var groupedByCodeAndThenId = groupedByCode.Select(group =>
    new { Key=group.Key, NestedGroup = group.ToLookup
                                         (result => result.MktCode, result => result.Id));

var dictionary = groupedByCodeAndThenId.ToDictionary
    (result => result.Key, result => result.NestedGroup);

Это даст вам Dictionary<Code, Lookup<MktCode, Id>> - я думаю, что вы хотите. Он полностью не тестировался.

Ответ 2

Вы можете создавать поисковые запросы (Виды словаря <, List < → ) с помощью group by into

var lines = new []
{
    new {Code = 1, MktCode = 10, Id = 1},
    new {Code = 2, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 10, Id = 12},
    new {Code = 1, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 20, Id = 14},
    new {Code = 2, MktCode = 20, Id = 1},
    new {Code = 2, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 5},
};

var groups = from line in lines
    group line by line.Code
    into codeGroup
    select new
    {
        Code = codeGroup.Key,
        Items = from l in codeGroup
            group l by l.MktCode into mktCodeGroup
            select new
            {
                MktCode = mktCodeGroup.Key, 
                Ids = from mktLine in mktCodeGroup
                    select mktLine.Id
            }
    };

Ответ 3

Вот как бы я это сделал:

Dictionary<Code, Dictionary<MktCode, List<Id>>> myStructure =
  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,
      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,
          g2 => g2.Select(e => e.Id).ToList()
        )
   )

Здесь разбивка процесса:

Группируйте элементы по коду и создавайте внешний словарь, где ключ - это код.

  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,

Для каждого из ключей во внешнем словаре перегруппируйте элементы по Mktcode и создайте внутренний словарь.

      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,

Для каждого из ключей во внутреннем словаре проецируйте идентификатор этих элементов и преобразуйте его в список.

          g2 => g2.Select(e => e.Id).ToList()
        )
   )