Как из одного словаря сформировать другой C#

У меня есть словарь предметов Dictionary<string, Dictionary<DateTime, NZMark>> subjectsDatesMarks, который хранит список дат с оценками.

Каким образом я могу привести его к следующему виду: Dictionary<DateTime, Dictionary<string, NZMark>> datesSubjectsMarks?

public enum NZMark
{
    One = 1,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Eleven,
    Twelve,
    WasAbsent,
    NotCertified,
    Exempted,
    Studied
}

Минимальный воспроизводимый пример:

var subjectsDatesMarks = new Dictionary<string, Dictionary<DateTime, NZMark>>();

subjectsDatesMarks.Add("math", new Dictionary<DateTime, NZMark>());
subjectsDatesMarks["math"].Add(new DateTime(2021, 03, 20), (NZMark)8);
subjectsDatesMarks["math"].Add(new DateTime(2021, 03, 21), (NZMark)8);
subjectsDatesMarks["math"].Add(new DateTime(2021, 03, 22), (NZMark)10);

subjectsDatesMarks.Add("PE", new Dictionary<DateTime, NZMark>());
subjectsDatesMarks["PE"].Add(new DateTime(2021, 03, 20), (NZMark)10);
subjectsDatesMarks["PE"].Add(new DateTime(2021, 03, 21), (NZMark)11);
subjectsDatesMarks["PE"].Add(new DateTime(2021, 03, 22), (NZMark)10);

var datesSubjectsMarks = MagickTransform(subjectsDatesMarks); // та самая функция для преобразования, которая мне нужна
var mathMark2021_03_22 = datesSubjectsMarks[new DateTime(2021, 03, 22)]["math"]; // 10

Ответы (1 шт):

Автор решения: VladD

Ну например так:

Dictionary<DateTime, Dictionary<string, NZMark>> datesSubjectsMarks =
    subjectsDatesMarks.SelectMany(e => e.Value.Select(dtmark => (subj: e.Key,
                                                                 dt: dtmark.Key,
                                                                 mark: dtmark.Value)))
                      .GroupBy(triple => triple.dt)
                      .ToDictionary(g => g.Key,
                                    g => g.ToDictionary(triple => triple.subj,
                                                        triple => triple.mark));

Проверка.


Ещё один вариант с query syntax:

Dictionary<DateTime, Dictionary<string, NZMark>> datesSubjectsMarks =
   (from kvp in subjectsDatesMarks
    let subj = kvp.Key
    from dtmark in kvp.Value
    let dt = dtmark.Key
    let mark = dtmark.Value
    group (subj, mark) by dt)
   .ToDictionary(g => g.Key,
                 g => g.ToDictionary(v => v.subj, v => v.mark));
→ Ссылка