2

I am presently sorting a C# list using the 'CompareTo' method in the object type contained in the list. I want to sort ascendingly all items by their WBS (Work Breakdown Structure) and I can manage this very well using the following code:

        public int CompareTo(DisplayItemsEntity other)
        {
            string[] instanceWbsArray = this.WBS.Split('.');
            string[] otherWbsArray = other.WBS.Split('.');

            int result = 0;

            for (int i = 0; i < maxLenght; i++)
            {
                if (instanceWbsArray[i].Equals(otherWbsArray[i]))
                {
                    continue;
                }
                else
                {    
                    result = Int32.Parse(instanceWbsArray[i]).CompareTo(Int32.Parse(otherWbsArray[i]));
                    break;
                }
            }
            return result;
        }

Now, I would like to be able to sort considering more than one parameter, as in the project name alphabetically, before considering the second which would be the WBS. How can I do this?

Jean-François Beaulieu
  • 4,305
  • 22
  • 74
  • 107

4 Answers4

9

I don't know the details of your class, so I'll provide an example using a list of strings and LINQ. OrderBy will order the strings alphabetically, ThenBy will order them by their lengths afterwards. You can adapt this sample to your needs easily enough.

var list = new List<string>
{
    "Foo",
    "Bar",
    "Foobar"
};
var sortedList = list.OrderBy(i => i).
    ThenBy(i => i.Length).
    ToList();
e_ne
  • 8,340
  • 32
  • 43
4

What we generally do in cases like yours is this:

public int CompareTo( SomeClass other )
{
    int result = this.SomeProperty.CompareTo( other.SomeProperty );
    if( result != 0 )
        return result;
    result = this.AnotherProperty.CompareTo( other.AnotherProperty );
    if( result != 0 )
        return result;
    [...]
    return result;
}
Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
2

I like Eve's answer because of it's flexibility but I'm kinda surprised that no-one has mentioned creating a custom IComparer<T> instance

IComparer<T> is a generic interface that defines a method for comparing two instances of the type T. The advantage of using IComparer<T> is that you can create implementations for each sort order you commonly use and then use these as and when necessary. This allows you to create a default sort order in the types CompareTo() method and define alternative orders separately.

E.g.

public class MyComparer
 : IComparer<YourType>
{
  public int Compare(YourType x, YourType y)
  {
     //Add your comparison logic here
  }
}

IComparer<T> is particularly useful for composition where you can do things like have a comparer which compares some properties of a given type using another comparer that operates on the type of the property.

It's also very useful if you ever need to define a sorting on a type you don't control. Another advantage it has is it doesn't require LINQ so can be used in older code (.Net 2.0 onwards)

RobV
  • 28,022
  • 11
  • 77
  • 119
0

First compare the project name alphabetically and if they are not equal return value, if not perform comparison based on second value

    public int CompareTo(DisplayItemsEntity other)
    {
       if(other.ProjectName.CompareTo(this.ProjectName) != 0)
       {
           return other.ProjectName.CompareTo(this.ProjectName)
       }

       //else do the second comparison and return


       return result;
    }
ajp
  • 1,440
  • 2
  • 13
  • 25