BrunoLM
BrunoLM

Reputation: 100341

How can I convert a list of items with ParentID into a tree?

I'm using SQL Server and Entity Framework. On my database I have the following data:

ID | Name   | ParentID
 1 | Fire   | null
 2 | Fire2  | 1
 3 | Fire3  | 2
 4 | Blast  | 2
 5 | Water  | null
 6 | Water2 | 5
 7 | WaterX | 5

I won't have massive data, so retrieving everything at once from the database is perfectly acceptable.

I want to retrieve this data and display on screen as a "tree".

    Fire
    Fire2
Fire3   Blast

     Water
Water2   WaterX

How should I do this? Should I create some sort of recursion to render it? Should I somehow convert the list to an IGrouping?

I'm having trouble converting the flat list into something that I can render hierarchically on the screen, how could I do that?

Upvotes: 1

Views: 617

Answers (2)

Saravana
Saravana

Reputation: 40594

If you can add another property to your class that has the child items like this:

public class Thing
{
    public Thing()
    {
        Things = new List<Thing>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public List<Thing> Things { get; set; }
}

Then you can easily group the items to their parents like this:

var things = new List<Thing>
{
    new Thing { Id = 1, Name = "Fire", ParentId = null },
    new Thing { Id = 2, Name = "Fire2", ParentId = 1 },
    new Thing { Id = 3, Name = "Fire3", ParentId = 2 },
    new Thing { Id = 4, Name = "Blast", ParentId = 2},
    new Thing { Id = 5, Name = "Water", ParentId = null },
    new Thing { Id = 6, Name = "Water2", ParentId = 5 },
    new Thing { Id = 7, Name = "Waterx", ParentId = 6 }
};

var groupedThings = new List<Thing>();

foreach (var thing in things)
{
    if (thing.ParentId != null)
    {
        things.First(t => t.Id == thing.ParentId).Things.Add(thing);
    }
    else
    {
        groupedThings.Add(thing);
    }
}

groupedThings.Dump();

Upvotes: 1

Enigmativity
Enigmativity

Reputation: 117064

This is the easiest way I know:

var things = new []
{
    new { Id = 1, Name = "Fire", ParentId = (int?)null },
    new { Id = 2, Name = "Fire2", ParentId = (int?)1 },
    new { Id = 3, Name = "Fire3", ParentId = (int?)2 },
    new { Id = 4, Name = "Blast", ParentId = (int?)2 },
    new { Id = 5, Name = "Water", ParentId = (int?)null },
    new { Id = 6, Name = "Water2", ParentId = (int?)5 },
    new { Id = 7, Name = "Waterx", ParentId = (int?)5 }
};

var tree = things.ToLookup(x => x.ParentId, x => new { x.Id, x.Name });

The tree looks like this:

tree

That should be fairly easy to render now.

Upvotes: 1

Related Questions