AaronS
AaronS

Reputation: 7713

Get Parent and then Child objects conditionally

I have a list of objects with the following basic structure:

class Person
{
    public int ID {get; set;}
    public bool ShowChildren {get; set;}
    public int ParentID {get; set;}

    // ...many other properties...
}

I need to return a list of Person parent classes that are orderd by their ID. If the ShowChildren flag is enabled, also return the children under their parent, ordered by their ID.

This is only one level deep, i.e. children won't have children.

I can write a linq statement to give me all of the parents, but I'm stuck on how to also include the sorted children when the parent's flag is enabled.

var People = PersonList
             .Where(x => x.ParentID == 0)
             .Orderby(x => x.ID)
             .ToList();

Upvotes: 4

Views: 1320

Answers (2)

Ry-
Ry-

Reputation: 225281

Sorry, if you only want to return parents unless explicitly requested (thanks, @Rawling!), a foreach loop is also nice.

var people = new List<Person>();

PersonList.Sort((a, b) => a.ID - b.ID);

foreach(Person p in PersonList) {
    if(p.ParentID == 0) { // Or whatever value you use to represent it
        people.Add(p);

        if(p.ShowChildren) {
            people.AddRange(PersonList.Where(c => c.ParentID == p.ID));
        }
    }
}

Upvotes: 4

Rawling
Rawling

Reputation: 50204

You can do this in two statements as follows:

// Build a lookup: parent ID => whether to show children.
var showChildrenDictionary = PersonList
    .Where(p => p.ParentID = 0)
    .ToDictionary(p => p.ID, p => p.ShowChildren);

// Get the desired list
var orderdedWithAppropriateChildren = PersonList
    // Discard children where not shown
    .Where(p => p.ParentID == 0 || showChildrenDictionary[p.ParentID])
    // Sort so parents and children are together and ordered by the parent
    .OrderBy(p => ((p.ParentID == 0) ? p.ID : p.ParentID))
    // Sort so parent is at start of group
    .ThenBy(p => p.ParentID != 0)
    // Sort so children are in order
    .ThenBy(p => p.ID)
    .ToList();

Upvotes: 1

Related Questions