Sorting a List object using different sort criterias

I have often had a list of objects that i need to sort. This can easyly be done through a SortedList, but this will only sort on the provided key. I would like to descide if i want to sort by my object.Property1 or object.Property2, ascending or descending etc. Also the SortedList give me problems if i have multiple objects with the same sort-ordinal.

The List<> type has a method, List<>.Sort(…) that can help out on this. In the example below, I have implemented a Person class, a PersonCollection : List and a PersonComparer : IComparer class. The PersonComparer has a constructor that takes a sortorder and a sortdirection as parameters. Calling the mypersonlist.Sort(…) method takes this PersonComparer object and carries out the actual sorting:

1
<br />using System;<br />using System.Collections.Generic;<br />using System.Text;<br />namespace SortingExample<br />{<br />        class Program<br />        {<br />                static void Main(string[] args)<br />                {<br />                        // Create a friendscollection<br />                        PersonCollection friends = new PersonCollection();<br />                        friends.Add(new Person("Kaj", 32));<br />                        friends.Add(new Person("Frank", 33));<br />                        friends.Add(new Person("Morten", 42));<br />                        Console.WriteLine("Age, Asc");<br />                        // Sort by age asc<br />                        PersonComparer sorter = new PersonComparer(PersonSort.Age, SortDirection.Ascending);<br />                        friends.Sort(sorter);<br />                        PrintNames(friends);<br />                        Console.WriteLine("Age, Desc");<br />                        // Sort by age desc<br />                        sorter.SortDirection = SortDirection.Descending;<br />                        friends.Sort(sorter);<br />                        PrintNames(friends);<br />                        Console.WriteLine("Name, Asc");<br />                        // Sort by name asc<br />                        sorter.SortDirection = SortDirection.Ascending;<br />                        sorter.Sort = PersonSort.Name;<br />                        friends.Sort(sorter);<br />                        PrintNames(friends);<br />                        Console.WriteLine("Name, Desc");<br />                        // Sort by name desc<br />                        sorter.SortDirection = SortDirection.Descending;<br />                        friends.Sort(sorter);<br />                        PrintNames(friends);<br />                }<br />


1
                /// <summary><br />                /// Printing out the persons of a PersonCollection<br />                /// </summary><br />                /// <param name="persons">A list of persons.</param><br />                public static void PrintNames(PersonCollection persons)<br />                {<br />                        foreach (Person friend in persons)<br />                        {<br />                                Console.WriteLine(string.Format("{0} – {1} years", friend.Name, friend.Age));<br />                        }<br />                }<br />        }


1
<br />        /// <summary><br />        /// The personobject will hold info about a person.<br />        /// </summary><br />        public class Person<br />        {<br />                private string _name;<br />                private int _age;<br />               <br />                /// <summary><br />                /// The name of the person.<br />                /// </summary><br />                public string Name<br />                {<br />                        get { return _name; }<br />                        set { _name = value; }<br />                }<br /><br />                /// <summary><br />                /// The age of the person.<br />                /// </summary><br />                public int Age<br />                {<br />                        get { return _age; }<br />                        set { _age = value; }<br />                }<br /><br />                /// <summary><br />                /// Initialize the person object with a name and an age.<br />                /// </summary><br />                /// <param name="name">The name of the person.</param><br />                /// <param name="age">The age of the person.</param><br />                public Person(string name, int age)<br />                {<br />                        Name = name;<br />                        Age = age;<br />                }<br />        }<br /><br />        /// <summary><br />        /// A list of persons…<br />        /// </summary><br />        public class PersonCollection : List<person><br />        {<br />        }<br /><br />        /// <summary><br />        /// The different sort orders<br />        /// </summary><br />        public enum PersonSort<br />        {<br />                Name,<br />                Age<br />        }<br /><br />        /// <summary><br />        /// Sort direction<br />        /// </summary><br />        /// <remarks>The emum values are used for multiplying on a compare result.<br />        /// This makes descending sorts appear in reverse order.<br />        /// </remarks><br />        public enum SortDirection<br />        {<br />                Ascending = 1,<br />                Descending = -1<br />        }<br /><br />        /// <summary><br />        /// This class takes care of comparing two persons. The<br />        /// class uses sorting and sort direction to determine which<br />        /// of the two objects has the highest value.<br />        /// </summary><br />        public class PersonComparer : IComparer<person><br />        {<br />                private PersonSort _sort;<br />                private SortDirection _sortDirection;<br />                public PersonSort Sort<br />                {<br />                        get { return this._sort; }<br />                        set { this._sort = value; }<br />                }<br />                public SortDirection SortDirection<br />                {<br />                        get { return this._sortDirection; }<br />                        set { this._sortDirection = value; }<br />                }<br /><br />                public PersonComparer(PersonSort sort, SortDirection direction)<br />                {<br />                        this._sort = sort;<br />                        this._sortDirection = direction;<br />                }<br />                #region IComparer<person> Members<br />                public int Compare(Person x, Person y)<br />                {<br />                        if (_sort == PersonSort.Age)<br />                        {<br />                        return x.Age.CompareTo(y.Age)*(int)_sortDirection;<br />                        }<br />                        else<br />                        {<br />                        return x.Name.CompareTo(y.Name)*(int)_sortDirection;<br />                        }<br />                }<br />                #endregion<br />        }<br />}<br />

Comments

One response to “Sorting a List object using different sort criterias”

  1. Lasse Rasch Avatar

    Great snippet… I have been using an array to do sorting of my objects until now.

    But this is much more simpel! Thnx…

    Your code has one error though. IComparer must take a object type, so this must be changed for it to compile:

    This blogger site will not let me use < or > in my comment, so i have replaced them with [ ]. This must of couse be changed back 🙂

    1. public class PersonCollection : List

    must be changed to :
    public class PersonCollection : List[Person]

    2. public class PersonComparer : IComparer

    must be changed to :
    public class PersonComparer : IComparer[Person]

    🙂
    /Lasse Rasch, R-Coding.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.