Solo812
Solo812

Reputation: 471

Sort List of Parent / Child Objects

I am having some trouble figuring out how to efficiently sort a list of parent items based on the child items.

I cannot just sort the child items. I need the result of the child item sort to affect the sorting of the parent list.

Essentially what I'm trying to do is sort the Parents in an order that reflects their children's name in descending order.

Is there a "linqish" way to do this once I already have a list of parents in memory? If so, any help you could afford would be great.

Here is an example....

//What I am trying to do is to figure out how to sort the order of parent1, parent2, parent3 
//based on the names of their children. 
//More specifically, the expected output would be:
//parent 1 (because she has a child with the name of Zoey), 
//parent 3 (because she has a child next in desc order with the name of Yolanda), 
//parent 2 (because her child names in desc order would Matt).

public class Parent
{
    public int id { get; set; }
    public int SortOrder { get; set; }
    //some properties
    public List<Child> Children { get; set; }

    public static List<Parent> GetSortedParentsByChildName()
    {
        List<Parent> myUnsortedList = new List<Parent>()
        {
            new Parent()
            {
                id = 1,
                Children = new List<Child>()
                {
                    new Child(1, "Billy"),
                    new Child(1, "Zoey"),
                    new Child(1, "Robert"),
                }
            },
            new Parent()
            {
                id = 2,
                Children = new List<Child>()
                {
                    new Child(1, "Gabe"),
                    new Child(1, "Matt"),
                    new Child(1, "Alyssa"),
                }
            },
            new Parent()
            {
                id = 3,
                Children = new List<Child>()
                {
                    new Child(1, "Will"),
                    new Child(1, "Bob"),
                    new Child(1, "Yolanda"),
                }
            },
        };


        return myUnsortedList; //.OrderBy(my actual question);
    }
}

public class Child
{
    public int id { get; set; }
    //some properties
    public string Name { get; set; }

    public Child(int id, string Name)
    {
        this.id = id;
        this.Name = Name;

    }
}

Upvotes: 0

Views: 2190

Answers (2)

Rahul Singh
Rahul Singh

Reputation: 21825

Okay so you can do it in this way as well:-

List<Parent> mySortedList =
    myUnsortedList
        .OrderByDescending(
            x => x.Children.OrderByDescending(z => z.Name).First().Name)
        .ToList();

Upvotes: 2

Enigmativity
Enigmativity

Reputation: 117174

This works for me to replace the return line in GetSortedParentsByChildName:

        var childrenMap =
            myUnsortedList
                .SelectMany(x => x.Children)
                .Select(x => x.Name)
                .Distinct()
                .OrderBy(n => n)
                .Select((n, i) => new { n, i })
                .ToDictionary(x => x.n, x => x.i);

        return myUnsortedList
            .Select(x => new
            {
                x,
                max = x.Children
                    .Select(y => childrenMap[y.Name])
                    .Max()
            })
            .OrderByDescending(x => x.max)
            .Select(x => x.x)
            .ToList();

I get this result:

parents in order

Upvotes: 0

Related Questions