web-dev-qa-db-fra.com

Trier une liste de cours personnalisée <T>

Je voudrais trier ma liste avec la propriété date.

Ceci est ma classe personnalisée:

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

Voici la List que je veux trier:

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

Ce que je veux faire, c'est trier la liste par la propriété date de la classe cTag . La date est au format suivant: dd.MM.yyyy.

J'ai lu quelque chose sur l'interface IComparable, mais je ne sais pas comment l'utiliser.

102
Werewolve

Une façon de faire est d'utiliser une variable 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); });
124
ahsteele

Vous avez raison de dire que votre classe cTag doit implémenter l'interface IComparable<T>. Ensuite, vous pouvez simplement appeler Sort() sur votre liste.

Pour implémenter l'interface IComparable<T>, vous devez implémenter la méthode CompareTo(T other). Pour ce faire, la méthode la plus simple consiste à appeler la méthode CompareTo du champ que vous souhaitez comparer, qui dans votre cas est la 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);
    }
}

Cependant, cela ne trierait pas bien, car cela utiliserait le tri classique sur les chaînes (puisque vous avez déclaré la date sous forme de chaîne). Donc, je pense que la meilleure chose à faire serait de redéfinir la classe et de déclarer la date non pas en tant que chaîne, mais en tant que DateTime. Le code resterait presque le même:

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

La seule chose que vous auriez à faire lors de la création de l'instance de la classe pour convertir votre chaîne contenant la date en type DateTime, mais cela peut être fait facilement, par exemple par la méthode DateTime.Parse(String).

46
Ondra C.

Dans ce cas, vous pouvez également trier à l'aide de LINQ:

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();
34
Yakimych
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))
);
11
Darin Dimitrov

Tout d’abord, si la propriété date stocke une date, stockez-la à l’aide d’un DateTime. Si vous analysez la date dans le tri, vous devez l'analyser pour chaque élément comparé, ce n'est pas très efficace ...

Vous pouvez ensuite créer un 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());

Vous pouvez même le faire en tant que délégué:

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

Vous avez raison - vous devez implémenter IComparable. Pour ce faire, déclarez simplement votre classe:

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

Dans CompareTo, vous venez d'implémenter votre algorithme de comparaison personnalisé (vous pouvez utiliser des objets DateTime pour cela, mais assurez-vous simplement de vérifier le type de "obj" en premier). Pour plus d'informations, voir ici et ici .

5
AJ.

Vous pouvez utiliser linq:

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

examinez la méthode de tri surchargée de la classe List. il y a plusieurs façons de le faire ... un.:. Votre classe personnalisée doit implémenter une interface IComparable, alors vous pouvez utiliser la méthode Sort de la classe List. 

3
Arseny

Merci pour toutes les réponses rapides.

Ceci est ma solution:

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

Merci

3
Werewolve

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

0
sansalk