Sort a Custom Class List<T>

C#Sorting

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

One way to do this is with a delegate

List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.date); });

Solution 2 - C#

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.

Solution 3 - C#

For this case you can also sort using LINQ:

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

Solution 4 - C#

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))
);

Solution 5 - C#

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;
          });

Solution 6 - C#

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.

Solution 7 - C#

You can use linq:

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

Solution 8 - C#

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

Solution 9 - C#

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.

Solution 10 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWerewolveView Question on Stackoverflow
Solution 1 - C#ahsteeleView Answer on Stackoverflow
Solution 2 - C#Ondra C.View Answer on Stackoverflow
Solution 3 - C#YakimychView Answer on Stackoverflow
Solution 4 - C#Darin DimitrovView Answer on Stackoverflow
Solution 5 - C#Matthew AbbottView Answer on Stackoverflow
Solution 6 - C#AJ.View Answer on Stackoverflow
Solution 7 - C#SirDemonView Answer on Stackoverflow
Solution 8 - C#sansalkView Answer on Stackoverflow
Solution 9 - C#ArsenyView Answer on Stackoverflow
Solution 10 - C#WerewolveView Answer on Stackoverflow