2

I am trying to learn advanced LINQ techniques, so how we could achieve, if possible with LINQ only, to select distinct items of a collection and merge their sub-items in a dictionary/struct or dynamic ExpandoObject?

Lets say i have these two class:

public class TestItem
{
    public int Id;
    public string Name;
    public List<TestSubItem> SubItems;
}

public class TestSubItem
{
    public string Name;
}

How can i create a single LINQ query(again, if possible) to select all distinct TestItem based on the Name property and if the same TestItem is found two time with the same name to merge the two List in the final result?

I know i could select distinct TestItem by doing the below code, but i'm stuck there:

    var result = items.GroupBy(item => item.Name)
                      .ToList();

Thanks in advance!

SlashJ
  • 687
  • 1
  • 11
  • 31

1 Answers1

1

A combination of a Select and an Aggregate on the groupings should get the job done. Finally, a ToDictionary call cleans everything up and gets rid of the potentially invalid ID field:

var result = items.GroupBy(item => item.Name)
                  .Select(g => g.Aggregate((i, j) =>
                  {
                      i.SubItems.AddRange(j.SubItems);
                      return i;
                  }))
                  .ToDictionary(k => k.Name, v => v.SubItems);

Alternatively, the query syntax is a bit more verbose, but I find it easier to read:

var result = (from item in items
                group item by item.Name
                into g
                let n =
                    from ti in g
                    select ti.Name
                let i =
                    from ti in g
                    from si in ti.SubItems
                    select si
                select new { n, i }).ToDictionary(k => k.n, v => v.i);
Jason Watkins
  • 3,766
  • 1
  • 25
  • 39