tags:

views:

157

answers:

9

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 sort:

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

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

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

+2  A: 

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.

Arseny
+4  A: 

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.age); });
ahsteele
You can also write the same thing with a lambda expression:`list.Sort((a,b) => a.date.CompareTo(b.date));`
Xavier Poinas
@Xavier for some reason my mind still always jumps to predicates first, though you are 100% correct that your Lambda expression would get the job done and is probably easier to read / understand.
ahsteele
+4  A: 

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.

AJ
`IComparable<T>` would probably be a better choice, as it is checked for in preference to `IComparable`: http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
Richard Szalay
You learn something every day... :o)
AJ
+2  A: 
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))
);
Darin Dimitrov
+2  A: 

You can use linq:

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

For this case you can also sort using LINQ:

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

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;
          });
Matthew Abbott
+2  A: 

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 think 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.

Ondra C.
A: 

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

Werewolve