Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Merging List of Objects into One Object

Tags:

c#

I get passed a list of small objects:

var smalls = new List<Small>();
smalls.AddRange( new Small[] { new Small{Name = "Aa", Id = 1, Value = "v1"},
                               new Small{Name = "Bb", Id = 1, Value = "v2"},
                               new Small{Name = "Cc", Id = 1, Value = "v3"},
                               new Small{Name = "Dd", Id = 1, Value = "v4"},
                               new Small{Name = "Ee", Id = 1, Value = "v5"},
                               new Small{Name = "Ff", Id = 1, Value = "v6"},
                               new Small{Name = "Gg", Id = 1, Value = "v7"} } );

From the above list I would like to populate an object that looks like this:

var large = new Large
    {
        Id = 1,
        Aa = "v1",
        Bb = "v2",
        Cc = "v3",
        Dd = "v4",
        Ee = "v5",
        Ff = "v6",
        Gg = "v7"
    }

The current code relies on the order of the list to populate the Large object however this does not feel secure enough and am looking for a more reliable way to map the list into the object.

Current code:

Large large = new Large
{
    Id = smalls[0].Id,
    Aa = smalls[0].Value,
    Bb = smalls[1].Value,
    Cc = smalls[2].Value,
    Dd = smalls[3].Value,
    Ee = smalls[4].Value,
    Ff = smalls[5].Value,
    Gg = smalls[6].Value
}

So I am looking to eliminate the assumption that they are in the correct order and populate the new fields based off of the Name string in the Small object into the corresponding field in the Large object.

Thanks for any input!!

like image 865
tvirch Avatar asked Mar 09 '23 05:03

tvirch


1 Answers

You can group values by Id, and make a few methods to extract values based on the Name field:

private static string GetValueByName(IDictionary<string,string> data, string name) {
    string res;
    return data.TryGetValue(name, out res) ? res : null;
}
private static Large MakeFromAttributes(IEnumerable<Small> data, int id) {
    var dictByName = data.ToDictionary(s => s.Name, s => s.Value);
    return new Large {
        Id = id
    ,   Aa = GetValueByName(dictByName, "Aa")
    ,   Bb = GetValueByName(dictByName, "Bb")
    ,   Cc = GetValueByName(dictByName, "Cc")
    ,   Dd = GetValueByName(dictByName, "Dd")
    ,   Ee = GetValueByName(dictByName, "Ee")
    ,   Ff = GetValueByName(dictByName, "Ff")
    ,   Gg = GetValueByName(dictByName, "Gg")
    };
}

With these helper methods you can construct a LINQ query as follows:

var largeList = smalls
    .GroupBy(s => s.Id)
    .Select(g => MakeFromAttributes(g, g.Key))
    .ToList();
like image 70
Sergey Kalinichenko Avatar answered Mar 20 '23 04:03

Sergey Kalinichenko