Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C#

Sorting with Objects on Multiple Fields

Rate me:
Please Sign up or sign in to vote.
3.80/5 (6 votes)
21 May 2007CPOL 69.1K   555   28   11
This article shows how to apply sorting on objects

Introduction

This article demonstrates how to apply sorting on objects. It is useful when you need to apply sorting on objects e.g. Object Person(Name, Age) and you want to apply sorting on Person->Name, or you may wish to apply sorting on multiple fields i.e. Person->name DESC + person->age DESC.

It is very useful when you want to apply multiple column sorting on GridViews with ObjectDataSource.

Using the Code

Using Reflection, its very easy to sort objects. I had used Lists<T> to sort objects and ObjectComparer class is inherited from IComparer<ComparableObject>.

ObjectComparer supports single as well as multiple sorting.

C#
//
//
//Test.cs 
//Created an array of Person object, for which i wish to apply sorting 

Person[] personArray = new Person[] { 
new Person("Ritesh", 26),
new Person("Arpan", 20),
new Person("Arpan", 23),
new Person("Hiren", 22),
new Person("Ankit", 22),
new Person("Dhaval", 23),
new Person("Gaurav", 25)
};

//Sort array on field Name in Ascending Order
Array.Sort(personArray, new ObjectComparer<Person>("Name"));

//Sort array on field Name Descending and Age Ascending
Array.Sort(personArray, new ObjectComparer<Person>("Name DESC, Age ASC",true));

ObjectComparer.cs

[Serializable]
public class ObjectComparer<ComparableObject> : IComparer<ComparableObject>
{
    #region Constructor
    public ObjectComparer()
    {
    }

    public ObjectComparer(string p_propertyName)
    {    
        //We must have a property name for this comparer to work
        this.PropertyName = p_propertyName;
    }

    public ObjectComparer(string p_propertyName, bool p_MultiColumn)
    {
        //We must have a property name for this comparer to work
        this.PropertyName = p_propertyName;
        this.MultiColumn = p_MultiColumn;
    }
    #endregion

    #region Property
    private bool _MultiColumn;
    public bool MultiColumn
    {
        get { return _MultiColumn; }
        set { _MultiColumn = value; }
    }

    private string _propertyName;
    public string PropertyName
    {
        get { return _propertyName; }
        set { _propertyName = value; }
    }
    #endregion 

    #region IComparer<ComparableObject> Members
    /// <summary>
    /// This comparer is used to sort the generic comparer
    /// The constructor sets the PropertyName that is used
    /// by reflection to access that property in the object to 
    /// object compare.
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public int Compare(ComparableObject x, ComparableObject y)
    {
        Type t = x.GetType();
        if (_MultiColumn) // Multi Column Sorting
        {
            string[] sortExpressions = _propertyName.Trim().Split(',');
            for (int i = 0; i < sortExpressions.Length; i++)
            {
                string fieldName, direction = "ASC";
                if (sortExpressions[i].Trim().EndsWith(" DESC"))
                {fieldName = sortExpressions[i].Replace(" DESC", "").Trim();
                direction = "DESC";
            }
            else
            {
                fieldName = sortExpressions[i].Replace(" ASC", "").Trim();
            }

            //Get property by name
            PropertyInfo val = t.GetProperty(fieldName);
            if (val != null)
            {
                //Compare values, using IComparable interface of the property's type
                int iResult = Comparer.DefaultInvariant.Compare
				(val.GetValue(x, null), val.GetValue(y, null));
                if (iResult != 0)
                {
                    //Return if not equal
                    if (direction == "DESC")
                    {
                        //Invert order
                        return -iResult;
                    }
                    else
                    {
                        return iResult;
                    }
                }
            }
            else
            {
                throw new Exception(fieldName + " is not a valid property to sort on. 
			It doesn't exist in the Class.");
            }
        }
        //Objects have the same sort order
        return 0;
    }
    else
    {
        PropertyInfo val = t.GetProperty(this.PropertyName);
        if (val != null)
        {
            return Comparer.DefaultInvariant.Compare
		(val.GetValue(x, null), val.GetValue(y, null));
        }
        else
        {
            throw new Exception(this.PropertyName + " 
	      is not a valid property to sort on. It doesn't exist in the Class.");
        }
    }
}
#endregion

}

//

Points of Interest

  • Sorting with objects
  • Multicolumn sorting with objects

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
India India
Proud Indian. Technology Evangelist. Over 18 years of experience in Product Engineering and Leading an Organization. Demonstrable organizational skills in putting together customer-focused teams of high caliber achievers who have delivered remarkable performances. He is creative and aggressive self-starter with integrative thinking skills, capable of forming and maintaining positive and productive working relationships in internal, external, independent, and team environments.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Dilip Baboo14-Jul-10 9:15
Dilip Baboo14-Jul-10 9:15 
GeneralOne more simple solution to compare objects. [modified] Pin
neal1233-Jan-10 19:22
neal1233-Jan-10 19:22 
GeneralRe: One more simple solution to compare objects. Pin
eddy_r v22-Feb-11 5:44
eddy_r v22-Feb-11 5:44 
GeneralImproved compare Pin
Gordon Fay15-Nov-07 7:05
Gordon Fay15-Nov-07 7:05 
QuestionWhat am i doing wrong Pin
abcdefgqwerty11-Jul-07 3:18
abcdefgqwerty11-Jul-07 3:18 
AnswerRe: What am i doing wrong Pin
Chazzysb22-Oct-08 0:04
Chazzysb22-Oct-08 0:04 
GeneralA better way Pin
uncle hammy25-Jun-07 3:26
uncle hammy25-Jun-07 3:26 
GeneralGreat ... but there is better ! Pin
Sebastien Ros22-May-07 2:58
Sebastien Ros22-May-07 2:58 
GeneralRe: Great ... but there is better ! Pin
scosta_FST31-May-07 20:35
scosta_FST31-May-07 20:35 
GeneralImprovement Pin
Itay Sagui17-May-07 8:48
Itay Sagui17-May-07 8:48 
GeneralRe: Improvement Pin
Ritesh Sutaria17-May-07 8:55
Ritesh Sutaria17-May-07 8:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.