Florian
Florian

Reputation: 4728

Convert a List<T> to a nested Dictionary<string, Dictionary<string, T>

I'm stuck on a basic problem. I need to convert a flat List to a Nested dictionary of type Dictionary<string,Dictionary<string,Dictionary<string,Dictionary<string,string>>>>

I've almost done except the fact that I need to group multiple properties, and I used an anonymous type for that. Here is an example :

List<ApprovalAction> Gen()
{
    return new List<ApprovalAction>
    {
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Homeworking", ParameterName = "to", ParameterValue="Approver" },
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Homeworking", ParameterName="subject", ParameterValue = "Aproval Request" },
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Homeworking", ParameterName="body", ParameterValue = "I would like an approval request"},
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Absence", ParameterName="to" , ParameterValue="Approver" },
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Absence", ParameterName="subject", ParameterValue = "Aproval Request" },
        new ApprovalAction { Name = "SendMailToApprover", Step="New", ApprovalRequestType = "Absence", ParameterName="body", ParameterValue = "I would like an approval request"}
    };
}


    var actions = Gen();
    var dico = actions
                .GroupBy(x => x.ApprovalRequestType)
                .ToDictionary(
                    gdc => gdc.Key,
                    gdc => gdc.GroupBy(a => a.Step)
                            .ToDictionary(dd => dd.Key, dd => dd.GroupBy(x => new { x.Name, x.Step, x.ApprovalRequestType }, (key, group) => new
                            {
                                Key = key.Name,
                                Result = group.ToDictionary(k => k.ParameterName, v => v.ParameterValue)
                            })));

This is the output of Linqpad :

enter image description here

Do you know by which code I can replace to avoid the IEnumerable ?

Thank you !

Upvotes: 2

Views: 808

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

IEnumerable<> comes from the final GroupBy. If you know that the innermost group would contain exactly one item, use Single(). Otherwise use First():

var dico = actions
    .GroupBy(x => x.ApprovalRequestType)
    .ToDictionary(
        gdc => gdc.Key,
        gdc => gdc.GroupBy(a => a.Step)
            .ToDictionary(dd => dd.Key, dd => dd.GroupBy(x => new { x.Name, x.Step, x.ApprovalRequestType }, (key, group) => new {
                Key = key.Name,
                Result = group.ToDictionary(k => k.ParameterName, v => v.ParameterValue)
            }).First()
        )
    );

Result of the query above looks like this:

LINQPad result

Upvotes: 2

Related Questions