2010-07-02 15 views
95

Chciałbym posortować listę za pomocą właściwości date.Sortuj niestandardową listę klas <T>

To jest mój zwyczaj klasa:

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

to List że chcę sortowania:

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

Co chcę zrobić jest sortowanie listy poprzez własność CTAG date klasa. Data jest w formacie: dd.MM.rrrr.

Przeczytałem coś o interfejsie IComparable, ale nie wiem, jak go używać.

Odpowiedz

118

Jednym ze sposobów na to jest z 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

Możesz również napisać to samo z wyrażeniem lambda: 'list.Sort ((a, b) => a.date.CompareTo (b.date));' –

+0

@Xavier z jakiegoś powodu mój umysł wciąż zawsze najpierw przeskakuje do predykatów, ale jesteś w 100% słuszny, że twoja ekspresja Lambda wykona zadanie i prawdopodobnie łatwiej je odczytać/zrozumieć. – ahsteele

+0

jak to się dzieje, lub jak byś łamał krawat konsekwentnie używając wyrażenia lambda? Co jeśli a.date == b.date here? list.Sort ((a, b) => a.date.CompareTo (b.date)); Czy spowodowałoby to problemy podczas stronicowania i te dwie przypadały na różne strony? – TheEmirOfGroofunkistan

3

spojrzenie na przeciążenie Metoda sortowania klasy Lista. jest na to kilka sposobów. jeden z nich: twoja niestandardowa klasa musi zaimplementować interfejs IComparable, a ty użyjesz cam Metoda sortowania klasy List.

5

Masz rację - trzeba zaimplementować IComparable. Aby to zrobić, wystarczy zadeklarować swoją klasę:

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

W CompareTo, wystarczy zaimplementować algorytm porównywania niestandardowy (można używać obiektów DateTime to zrobić, ale po prostu mieć pewność, aby najpierw sprawdzić typ „obj”) . Aby uzyskać więcej informacji, zobacz here i here.

+7

'IComparable ' prawdopodobnie byłby lepszym wyborem, ponieważ jest sprawdzane zamiast "IComparable": http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx –

+0

Każdego dnia uczysz się czegoś ...: 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

Można użyć LINQ:

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

W tym przypadku można również sortować za pomocą LINQ:

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

Pierwsze rzeczy pierwsze, jeśli właściwość data zapisuje datę, sklep używając DateTime. Jeśli analizować datę poprzez sortowanie trzeba analizować je dla każdej pozycji są porównywane, że nie jest bardzo skuteczny ...

Następnie można dokonać 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()); 

Można nawet zrobić to jako delegat:

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

Masz rację, że klasa CTAG musi wdrożyć IComparable<T> interfejs. Następnie możesz po prostu zadzwonić pod numer Sort() na swoją listę. Aby uzyskać implementację interfejsu IComparable<T>, należy wdrożyć metodę . Najprościej to zrobić, aby wywołać metodę CompareTo pola, które chcesz porównać, które w twoim przypadku jest datą.

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

Jednak to nie rodzaj dobrze, bo byłoby to wykorzystać klasyczny sortowania na sznurkach (ponieważ datę jako ciąg zadeklarowanej).Więc myślę, że najlepiej byłoby zmienić definicję klasy i zadeklarować datę nie jako łańcuch, ale jako DateTime. Kod zatrzymałbym się prawie tak samo:

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

Jedyną rzeczą, którą trzeba zrobić podczas tworzenia instancji klasy do konwersji ciąg zawierający datę do typu DateTime, ale można to zrobić łatwo np metodą DateTime.Parse(String).

2

Dzięki za wszystkie szybkie odpowiedzi.

to my rozwiązanie:

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

Dzięki

0

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

Powiązane problemy