2010-07-02 19 views
95

Me gustaría ordenar mi lista con la propiedad date.Ordenar una lista de clases personalizada <T>

Esta es mi clase personalizada:

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

Una éste es el List que quiero para ordenar:

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

Lo que quiero hacer es ordenar la lista por la propiedad date del cTag clase. La fecha está en el formato: dd.MM.aaaa.

He leído algo sobre la interfaz IComparable, pero no sé cómo usarla.

Respuesta

118

Una forma de hacerlo es con un 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); }); 
+81

También puede escribir lo mismo con una expresión lambda: 'list.Sort ((a, b) => a.date.CompareTo (b.date));' –

+0

@Xavier por alguna razón mi mente aún siempre salta a los predicados primero, aunque está 100% correcto de que su expresión Lambda hará el trabajo y probablemente sea más fácil de leer/comprender. – ahsteele

+0

¿Cómo hace esto, o cómo lo harías, romper una corbata consistentemente con la expresión lambda? ¿Qué pasa si a.date == b.date aquí? list.Sort ((a, b) => a.date.CompareTo (b.date)); ¿Esto crearía problemas cuando las paginas de búsqueda y estos dos caen en diferentes páginas? – TheEmirOfGroofunkistan

3

mira el método Sort sobrecargado de la clase List. hay algunas formas de hacerlo. uno de ellos: su clase personalizada tiene que implementar la interfaz IComparable y luego puede usar el método Sort de la clase List.

5

Tiene usted razón - es necesario implementar IComparable. Para ello, basta con declarar una clase:

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

En CompareTo, que acaba de poner en marcha su algoritmo de comparación personalizada (se puede utilizar objetos DateTime para hacer esto, pero sólo asegúrese de comprobar el tipo de "obj" primero) . Para obtener más información, consulte here y here.

+7

'IComparable ' probablemente sea una mejor opción, ya que se comprueba con preferencia a 'IComparable': http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx –

+0

Aprende algo todos los días ...: o) –

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

Puede utilizar LINQ:

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

Para este caso también se puede ordenar el uso de LINQ:

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

Lo primero es lo primero, si la propiedad de fecha es el almacenamiento de una fecha, tienda usando un DateTime. Si analizar la fecha a través de la clase que tiene que analizarlo para cada elemento que se comparan, eso no es muy eficiente ...

A continuación, puede hacer una 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()); 

Incluso puede hacerlo como un delegado:

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

tiene razón en que la clase debe implementar cTag IComparable<T> interfaz. Luego puede llamar al Sort() en su lista.

Para implementar la interfaz IComparable<T>, debe implementar el método CompareTo(T other). La forma más fácil de hacerlo es llamar al método CompareTo del campo que desea comparar, que en su caso es la fecha.

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

Sin embargo, esto no se ordenen bien, porque esto sería utilizar la clasificación clásica de cuerdas (ya que declaró la fecha como cadena).Así que creo que lo mejor que se puede hacer sería redefinir la clase y declarar la fecha no como una cadena, sino como DateTime. El código se quedaría casi el mismo:

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

Lo único que tendría que hacer al crear la instancia de la clase para convertir su cadena que contiene la fecha en tipo DateTime, pero se puede hacer fácilmente, por ejemplo, por el método DateTime.Parse(String).

2

Gracias por todas las respuestas rápidas.

Este es mi solución:

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

Gracias

0

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

Cuestiones relacionadas