Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a collection based on a subcollection property

I would like to sort a collection based on a subcollection property.

//the subcollection
public class Salary
{
   public int SalaryId {get;set;}
   public int SalaryYear {get;set;}
   public double SalaryValue {get;set;} //this is the field we want to sort the parent collection "Person"
}

//the main collection
public class Person
{
   public int PersonId {get;set;}
   public string PersonName {get;set;}
   public List<Salary> Salaries {get;set;}
}

Below just for testing purpose, I'm preparing my collection of person with Salaries inner collections each one:

List<Person> people = new List<Person>();
//add two salaries for Junior
people.Add(new Person { PersonId = 1, PersonName = "Junior" });
people[0].Salaries.Add(new Salary { SalaryId=1, SalaryYear=2011, SalaryValue=80000 });
people[0].Salaries.Add(new Salary { SalaryId=2, SalaryYear=2010, SalaryValue=70000 });

//add two salaries for Johanna
people.Add(new Person { PersonId = 2, PersonName = "Johanna" });
people[0].Salaries.Add(new Salary { SalaryId=3, SalaryYear=2011, SalaryValue=40000 });
people[0].Salaries.Add(new Salary { SalaryId=4, SalaryYear=2010, SalaryValue=30000 });

Now we want to sort the people collection, but using their inner collection SalaryValue as parameter.

How can I sort List but using LINQ / Lambda expressions on Salaries inner collection?

So I would have:

PersonName: Johanna, SalaryValue=30000, SalaryYear=2010
PersonName: Johanna, SalaryValue=40000, SalaryYear=2011
PersonName: Junior, SalaryValue=70000, SalaryYear=2010
PersonName: Junior, SalaryValue=80000, SalaryYear=2011
like image 306
Junior Mayhé Avatar asked Aug 12 '10 20:08

Junior Mayhé


2 Answers

To me, that looks like:

var query = from person in people
            from salary in person.Salaries
            orderby salary.SalaryValue
            select new { person, salary };

foreach (var pair in query)
{
    Console.WriteLine(pair);
}

Note that you're not really sorting a collection of people - you're sorting a collection of (person, salary), which is what the flattening effect of having two from clauses does.

(The above won't provide exactly the same output, but once you've got the person and their salary, you can get at the other values.)

like image 88
Jon Skeet Avatar answered Nov 02 '22 23:11

Jon Skeet


It looks like Jon's logic is correct, but the sample code doesn't match the OP's. It should probably be more like this:

var query = from person in people
            from salary in person.Salaries
            orderby salary.SalaryValue
            select new { person.PersonName, salary.SalaryValue, salary.SalaryYear };

foreach (var tuple in query)
{
    Console.WriteLine(tuple);
}
like image 2
Steven Sudit Avatar answered Nov 02 '22 23:11

Steven Sudit