Search code examples
c#dictionaryanonymous-types

How to get a nested dictionary using extension methods in C#?


I want to make a function that receives a csv file and returns a nested dictionary. The csv file format looks like this(but there's no space between values):

FilmMaker,   MovieTitle,      EndDate
FunnyM,      F1,              20191210
FunnyM,      F2,              20191211
FunnyM,      F3,              20191212
FunnyM,      F4,              20191213
FunnyM,      F5,              20191214
SadM,        S1,              20191210
SadM,        S2,              20191211
SadM,        S3,              20191212
SadM,        S4,              20191213
SadM,        S5,              20191214
ScaryM,      C1,              20191210
ScaryM,      C2,              20191211
ScaryM,      C3,              20191212
ScaryM,      C4,              20191213
ScaryM,      C5,              20191214

And this is the function I'm working on:

public static Dictionary<string, Dictionary<string, string>> CSV_to_dictionary(String csvFileName)
{
    var data = File.ReadAllLines("movies.csv", Encoding.Default);

    var d = data.Skip(1)
                .Select(line => line.Split(',').ToList())
                .Select(a => new { FilmMaker= a[0], MovieTitle= a[1], EndDate= DateTime.ParseExact(a[2], "yyyyMMdd", CultureInfo.InvariantCulture) })
                .GroupBy(o => o.FilmMaker)
                .Select(g => new { FilmMaker= g.Key, info = g.Where(m => m.EndDate> new DateTime(2019, 12, 10)).OrderBy(m => m.EndDate).Skip(1).First() })
                .ToDictionary(m => m.info.MovieTitle,
                              m => new { FilmMaker= m.FilmMaker, EndDate= m.info.EndDate.ToString("yyyyMMdd") });

    return d;
}

The main goal is to extract one movie per FilmMaker on some conditions and make a nested dictionary like:

dictionary_movie = { "F3": { "FilmMaker":"FunnyM", "EndDate":"20191212" },
                     "S3": { "FilmMaker":"SadM",   "EndDate":"20191212" },
                     "C3": { "FilmMaker":"ScaryM", "EndDate":"20191212" } }

and refer to the dictionary in the main program.

The problem is that the return type of the function isn't the same as the result of the extension methods. I thought it would be Dictionary<string, Dictionary<string, string>>, but it's Dictionary<string, <anonymous type: string, string>>. How can I change the anonymous type to the nested dictionary type? Is it possible to do it in a extension method?


Solution

  • It looks like to me that you could replace this final line

    m => new { FilmMaker= m.FilmMaker, EndDate= m.info.EndDate.ToString("yyyyMMdd") }
    

    with this one

    m => new Dictionary<string, string> { { "FilmMaker", m.FilmMaker }, { "EndDate", m.info.EndDate.ToString("yyyyMMdd") } }
    

    and it's gonna create a new Dictionary<string, string> as the value instead of using an anonymous type.