Click here to Skip to main content
6,632,966 members and growing! (19,184 online)
Email Password   helpLost your password?
General Programming » Algorithms & Recipes » General     Intermediate

Sorting with Objects on multiple fields

By Ritesh Sutaria

This article shows how to apply sorting on objects
C# 2.0, Windows, .NET 2.0VS2005, Dev
Posted:16 May 2007
Updated:21 May 2007
Views:21,428
Bookmarked:25 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
4 votes for this article.
Popularity: 2.11 Rating: 3.50 out of 5
1 vote, 25.0%
1

2
1 vote, 25.0%
3
1 vote, 25.0%
4
1 vote, 25.0%
5

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.

//
//
//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 Decending 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

Did you learn anything interesting/fun/annoying while writing the code? Did you do anything particularly clever or wild or zany?

History

Sorting with objects

Multicolumn sorting with objects

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Ritesh Sutaria


Member
Ritesh Sutaria has about 7+ years of IT experience on various technologies like ASP.net, PHP, VB, Oracle, PGSql, Sql Server. He has worked on various platforms including Windows, Linux. He has a powerfull problem solving skills which actually makes complex problems into simple problems.
Location: India India

Other popular Algorithms & Recipes articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 8 of 8 (Total in Forum: 8) (Refresh)FirstPrevNext
GeneralImproved compare PinmemberGordon Fay8:05 15 Nov '07  
GeneralWhat am i doing wrong Pinmemberabcdefgqwerty4:18 11 Jul '07  
GeneralRe: What am i doing wrong PinmemberChazzysb1:04 22 Oct '08  
GeneralA better way Pinmemberuncle hammy4:26 25 Jun '07  
GeneralGreat ... but there is better ! PinmemberSbastien Ros3:58 22 May '07  
GeneralRe: Great ... but there is better ! Pinmemberscosta_FST21:35 31 May '07  
GeneralImprovement PinmemberItay Sagui9:48 17 May '07  
GeneralRe: Improvement PinmemberRitesh Sutaria9:55 17 May '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 21 May 2007
Editor:
Copyright 2007 by Ritesh Sutaria
Everything else Copyright © CodeProject, 1999-2009
Web18 | Advertise on the Code Project