MetaGuru
MetaGuru

Reputation: 43873

How can I sort a List<T> by multiple T.attributes?

Let's say I have a List of Songs.

Song {
    public string Name = "";
    public int PlayOrder = 0;
    }

Now I want to sort them first by PlayOrder starting at zero and second by Name alphabetically.

So an example set of sorted results would be (Name, PlayOrder):

/*
    Pachelbel's Canon, 0
    A Happy Song, 4
    Beethoven's 5th, 4
    Some Other Song, 7
*/

See how the PlayOrder = 4 ones are in order alphabetically? That's what I'm going for.

Right now I have it only sorting by one field:

List<Song> final = new List<Song>();

...

final.Sort((x, y) => x.PlayOrder.CompareTo(y.PlayOrder));

return final;

How can I also sort by Name as demonstrated above?

Upvotes: 57

Views: 50772

Answers (3)

Corniel Nobel
Corniel Nobel

Reputation: 429

If you only have one preferred way of sorting your Song class, you should implement IComparable and/or IComparable<Song>:

List<Song> songs = GetSongs();
songs.Sort(); // Sorts the current list with the Comparable logic

If you have multiple ways how you want to store your list, IEqualityComparer<T> is the interface you would like to implement. Then you can provide that comparer as argument in List<T>Sort().

Upvotes: 0

tster
tster

Reputation: 18247

If you want to continue using the sort method you will need to make your comparison function smarter:

final.Sort((x, y) => {
    var ret = x.PlayOrder.CompareTo(y.PlayOrder);
    if (ret == 0) ret = x.Name.CompareTo(y.Name);
    return ret;
});

If you want to use LINQ then you can go with what K Ivanov posted.

Upvotes: 53

Kris Ivanov
Kris Ivanov

Reputation: 10598

return final.OrderBy(s => s.PlayOrder).ThenBy(s => s.Name);

Upvotes: 106

Related Questions