user1932923
user1932923

Reputation: 384

Merge two lists using Linq

I have three Models something like this:

public class Section
{
  public string Id {get; set;}

  public SubSection[] SubSections {get; set;}

  public Item[] Items {get; set;}
}

public class SubSection
{
  public string Id {get; set;}

  public string sectionId {get; set;}

  public Item[] Items {get; set;}
}

public class Item
{
  public string Id {get; set;}

  public string sectionId {get; set;}
}

Now when I get the result back I get back list of Sections and Items and would like to merge these two lists to put it into the above Models.

Everything is connected with Section Id; determining where the item goes in SubSection or directly under section and the subsections go under section array.

Is there a good way to do this using Linq?

Example:

Item { id = "123", sectionId = "456"}
Item {id = "234", sectionId = "786"}

SubSection {id = "211", sectionId = "786", Items = null}
SubSection {id = "210", sectionId = 456", Items[] = new Item() {"123"}}

Section {id = 786, subsections[] = null, items[] =  new Item() {"234" }}
Section {id = 456, subsection[] = new SubSection { id = 210}, items = null}

Upvotes: 0

Views: 404

Answers (2)

Victor Procure
Victor Procure

Reputation: 883

var sections = new List<Section>();
        var subSections = new List<SubSection>();
        var items = new List<Item>();

        var itemSections = from s in sections
                           let i = items.Where(j => j.sectionId == s.Id).DefaultIfEmpty().ToArray()
                           let ss = subSections.Where(j => j.sectionId == s.Id).DefaultIfEmpty().ToArray()

                           select new Section
                           {
                               Id = s.Id,
                               SubSections = ss,
                               Items = i
                           };

This should work, haven't tested. Not sure what you mean by Merge tho

Upvotes: 0

Matthew Haugen
Matthew Haugen

Reputation: 13296

LINQ is good at reading and transforming, but not at modifying items where they stand. It's doable (a right way and a "wrong" way), but unless you specifically need that, I'll focus on what you're asking here.

List<SectionWithoutCollections> sections;
List<SubSectionWithoutCollections> subSections;
List<Item> items;

var subSectionsWithItems = subSections
    .GroupJoin(items, a => a.Id, b => b.SectionId, (a,b) => new SubSection
               {
                   Id = a.Id,
                   SectionId = a.SectionId,
                   Items = b.ToArray()
               });

var sectionsWithItems = sections
    .GroupJoin(subSectionsWithItems, a => a.Id, b => b.SectionId, (a,b) => new { Section = a, SubSections = b })
    .GroupJoin(items, a => a.Section.Id, b => b.SectionId, (a,b) => new Section
               {
                   Id = a.Section.Id,
                   Items = b.ToArray(),
                   SubSections = a.SubSections.ToArray()
               });

I did this in two steps, but you could do it in one, if readability didn't matter (which is always does).

It's pretty straight-forward once you know the methods, but basically I put all the subsections and items together, then I put all the sections and subsections together, then I put all the sections-and-subsections and items together.

Just note that any orphaned items or subsections (i.e. those for which no section or subsection with SectionId exist) will be thrown out. But that's bad relational anyway, so that's acceptable, as far as I know.

Upvotes: 1

Related Questions