[c#] Sort a Custom Class List<T>

I would like to sort my list with the date property.

This is my custom class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test.Web
{
    public class cTag
    {
        public int id { get; set; }
        public int regnumber { get; set; }
        public string date { get; set; }
    }
}

An this is the List that I want to sort:

List<cTag> Week = new List<cTag>();

I want to sort the List by the date property of the cTag class. The date is in the format dd.MM.yyyy.

I read something about the IComparable interface, but I don't know how to use it.

This question is related to c# sorting

The answer is


You are correct that your cTag class must implement IComparable<T> interface. Then you can just call Sort() on your list.

To implement IComparable<T> interface, you must implement CompareTo(T other) method. The easiest way to do this is to call CompareTo method of the field you want to compare, which in your case is date.

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public string date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

However, this wouldn't sort well, because this would use classic sorting on strings (since you declared date as string). So I think the best think to do would be to redefine the class and to declare date not as string, but as DateTime. The code would stay almost the same:

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public DateTime date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

Only thing you'd have to do when creating the instance of the class to convert your string containing the date into DateTime type, but it can be done easily e.g. by DateTime.Parse(String) method.


YourVariable.Sort((a, b) => a.amount.CompareTo(b.amount));

List<cTag> week = new List<cTag>();
week.Sort((x, y) => 
    DateTime.ParseExact(x.date, "dd.MM.yyyy", CultureInfo.InvariantCulture).CompareTo(
    DateTime.ParseExact(y.date, "dd.MM.yyyy", CultureInfo.InvariantCulture))
);

You are right - you need to implement IComparable. To do this, simply declare your class:

public MyClass : IComparable
{
  int IComparable.CompareTo(object obj)
  {
  }
}

In CompareTo, you just implement your custom comparison algorithm (you can use DateTime objects to do this, but just be certain to check the type of "obj" first). For further information, see here and here.


First things first, if the date property is storing a date, store it using a DateTime. If you parse the date through the sort you have to parse it for each item being compared, that's not very efficient...

You can then make an IComparer:

public class TagComparer : IComparer<cTag>
{
    public int Compare(cTag first, cTag second)
    {
        if (first != null && second != null)
        {
            // We can compare both properties.
            return first.date.CompareTo(second.date);
        }

        if (first == null && second == null)
        {
            // We can't compare any properties, so they are essentially equal.
            return 0;
        }

        if (first != null)
        {
            // Only the first instance is not null, so prefer that.
            return -1;
        }

        // Only the second instance is not null, so prefer that.
        return 1;
    }
}

var list = new List<cTag>();
// populate list.

list.Sort(new TagComparer());

You can even do it as a delegate:

list.Sort((first, second) =>
          {
              if (first != null && second != null)
                  return first.date.CompareTo(second.date);

              if (first == null && second == null)
                  return 0;

              if (first != null)
                  return -1;

              return 1;
          });

Thanks for all the fast Answers.

This is my solution:

Week.Sort(delegate(cTag c1, cTag c2) { return DateTime.Parse(c1.date).CompareTo(DateTime.Parse(c2.date)); });

Thanks


For this case you can also sort using LINQ:

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();

look at overloaded Sort method of the List class. there are some ways to to it. one of them: your custom class has to implement IComparable interface then you cam use Sort method of the List class.


You can use linq:

var q = from tag in Week orderby Convert.ToDateTime(tag.date) select tag;
List<cTag> Sorted = q.ToList()