Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Normalize data with LINQ

Assume we have some denormalized data, like this:

List<string[]> dataSource = new List<string[]>();
string [] row1 = {"grandParentTitle1", "parentTitle1", "childTitle1"}; 
string [] row2 = {"grandParentTitle1", "parentTitle1", "childTitle2"};
string [] row3 = {"grandParentTitle1", "parentTitle2", "childTitle3"};
string [] row4 = {"grandParentTitle1", "parentTitle2", "childTitle4"};
dataSource.Add(row1);

I need to normalize it, e.g. to get IEnumerable< Child > with Child.Parent and Child.Parent.GrandParent filled.

Imperative way is more or less clear. Will it be shorter with Linq?

Better in one query, and this should be expandable for more entities.

I tried something like separately create IEnumerable< GrandParent >, then IEnumerable< Parent > with assigning etc.

PLease make a hint could this be achieved in a functional way?

like image 348
rudnev Avatar asked Feb 27 '10 20:02

rudnev


1 Answers

You can do exactly what you want using group by. Unfortunately my knowledge of the C# LINQ syntax is limited, so I just can show you the way calling extension method GroupBy.

var normalized = dataSource
    .GroupBy(source => source[0], (grandParent, grandParentChilds) => new { GrandParent = grandParent, Parents = grandParentChilds
        .GroupBy(source => source[1], (parent, parentChilds) => new { Parent = parent, Children = from source in parentChilds select source[2]}) });

foreach (var grandParent in normalized)
{
    Console.WriteLine("GrandParent: {0}", grandParent.GrandParent);
    foreach (var parent in grandParent.Parents)
    {
        Console.WriteLine("\tParent: {0}", parent.Parent);
        foreach (string child in parent.Children)
            Console.WriteLine("\t\tChild: {0}", child);
    }
}
like image 160
Fede Avatar answered Nov 09 '22 09:11

Fede