List<niveau1>
maliste = new List<niveau1>();
....
maliste.Sort(); // Ça, c'est ce que je voudrais faire, en précisant "ascendant" ou "descendant
List<niveau1>
maliste = new List<niveau1>();
....
maliste.Sort(); // descendant
maliste.Reverse(); // ascendant ( on inverse le sens )
public class main
{
List<niveau1> maliste = new List<niveau1>();
....
maliste.Sort(); // Ça, c'est ce que je voudrais faire, en précisant "ascendant" ou "descendant"
}
public class niveau1
{
string prop11;
string prop12;
niveau2 ma_sous_classe = new niveau2(); // classe incorporée à examiner
string prop13;
autre_classe mon_autre_classe = new autre_classe();
...
}
public class niveau2
{
string prop21;
int prop22;
string mon_critere_de_tri; // C'est ce qu'il faut comparer, en ascendant ou descendant
bool prop23;
...
}
public class niveau1 { public string prop11 { get; set; } public string prop12 { get; set; } public List<niveau2> ma_sous_classe { get; set; } = new List<niveau2>(); // classe incorporée à examiner public string prop13 { get; set; } } public class niveau2 { public string prop21 { get; set; } public int prop22 { get; set; } public string mon_critere_de_tri { get; set; } // C'est ce qu'il faut comparer, en ascendant ou descendant public bool prop23 { get; set; } }
List<niveau1> source = new List<niveau1>(); List<niveau1> triLinq = source.OrderBy(n => n.ma_sous_classe.First().mon_critere_de_tri).ToList(); List<niveau1> triLinqInverse = source.OrderByDescending(n => n.ma_sous_classe.First().mon_critere_de_tri).ToList(); List<niveau1> triLinq2criteres = source.OrderBy(n => n.ma_sous_classe.First().mon_critere_de_tri).ThenByDescending(n1 => n1.ma_sous_classe.First().prop22).ToList();
public class niveau1:IComparable { public string prop11 { get; set; } public string prop12 { get; set; } public List<niveau2> ma_sous_classe { get; set; } = new List<niveau2>(); // classe incorporée à examiner public string prop13 { get; set; } public int CompareTo(object obj)//compareTo retourne 1 ou -1 selon qui est le plus grand, et 0 en cas d'égalité, comme on ne sait jamais quand retourner 1 o =1, le plus simple est d'utilser le CompareTo de notre critère { return ma_sous_classe.First().mon_critere_de_tri.CompareTo(((niveau1)obj).ma_sous_classe.First().mon_critere_de_tri); } } public class niveau2 { public string prop21 { get; set; } public int prop22 { get; set; } public string mon_critere_de_tri { get; set; } // C'est ce qu'il faut comparer, en ascendant ou descendant public bool prop23 { get; set; } }
source.Sort();//tri dans un sens source.Reverse();//inversion de l'ordre de tri
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionJ'avais quasiment implémenté la version IComparable, mais là où je n'ai pas su faire, c'est le contenu de la méthode CompareTo.
A priori, ma préférence va plutôt vers cette méthode, car elle ne modifie pas la classe d'origine.
Je suppose qu'en ajoutant une propriété Order à la la classe niveau1 on peut gérer le sens du tri.oui, avec ce paramètre tu inverses la sortie de CompareTo
Je n'ai pas bien compris l'histoire des champs publics. Les propriétés doivent être publiques pour pouvoir être utilisées dans des instances de la classe. Les classes doivent être publiques puisque à l'extérieur de la classe Main. Dans mon exemple, il est évident que cela ne peut pas marcher puisque sans modificateur, les propriétés sont vues comme privées. Mais j'ai déjà répondu sur ce point. Sinon quel est le problème ?Un champ n'est pas une propriété.
class Personne { string prenom; string nom; DateTime naissance public Personne(string Prenom, string Nom, DateTime Naissance) { prenom = Prenom; nom = Nom; naissance = Naissance } }
class Personne { string prenom;//champ DateTime naissance public Personne(string Prenom, string Nom, DateTime Naissance) { prenom = Prenom; this.Nom = Nom; naissance = Naissance } public string Prenom//propriété { get {return prenom;} } public string NumeroTel {get; set;}//notation alternative à la propriété, quand on n'a pas besoin de la variable interne public string Nom {get; private set}//notation alternative en lecture seule }
Le fait que la méthode Linq crée une copie de la classe 1 me gêne un peu, car cette classe fait partie d'une classe de niveau 0 (tant qu'à faire...) et cela m'obligerait à remplacer l'instance de la classe d'origine par la nouvelle créée par Linq. Je suppose que ce n'est pas important, mais j'ignore les conséquences dans les variables externes à la classe 0 qui utilisent des références à la classe 1 ou la classe 2 (genre classe0.classe1.classe2.prop22).Linq ne crée pas de nouvelle instance, il crée une autre collection avec les mêmes instances (et rien ne t'empêche de stocker le résultat dans la collection source).
public class album_class : IComparable, le compilateur me dit que "'album_class' n'implémente pas le membre d'interface 'IComparable.CompareTo(object)'". Pourtant J'ai dans ma classe la méthode CompareTo :
public class album_class : IComparable { public bool SortDesc { get; set; } public alb_common_class common = new alb_common_class(); public alb_styles_class styles = new alb_styles_class(); public List<alb_slide_class> slides = new List<alb_slide_class>(); public int CompareTo(album_class album) { if (album == null) return 1; else if (SortDesc) return -(this.common.path.CompareTo(album.common.path)); else return this.common.path.CompareTo(album.common.path); }(common.path est un String)
EDIT : Je viens de remplacer "album_class album" par "object album" et le compilateur ne dit plus rien (sauf qu'il faut caster album en album_class). Ah, ces surcharges... Il faut veiller à respecter les paramètres.
PS : Je vais corriger mes champs publics en propriétés en rajoutant { get; set; }. J'ai bien compris ? Si oui, y'a du boulot ! Notes que de toute façon il est prévu que n'importe qui (??? c'est MON programme) puisse modifier ces valeurs, autant en écriture qu'en lecture
class Personne { string prenom;//champ DateTime naissance public Personne(string Prenom, string Nom, DateTime Naissance) { prenom = Prenom; this.Nom = Nom; naissance = Naissance } public string Prenom//propriété { get { if(prenom == "JeSaisPlus" && Nom == "JaiJamaisSu") return "Maxime"; return prenom; } } public string NumeroTel {get; set;}//notation alternative à la propriété, quand on n'a pas besoin de la variable interne public string Nom {get; private set}//notation alternative en lecture seule }
public Remerciements Merci { get; set; } = new Remerciements();
/// <summary> /// Paramètres des vignettes : titre, nom de fichier et ratio /// </summary> public class alb_slide_class : IComparable { public alb_slide_class() { } public alb_slide_class(string slide_title, string slide_path, string slide_ratio) { mPath = slide_path; mTitle = slide_title; mRatio = slide_ratio; } private string mPath = "", mTitle = "", mRatio = "1.5"; [XmlIgnore] public bool Modified { get; set; } [XmlIgnore] public bool sortdesc { get; set; } public string file { get { return mPath; } set { if (value != mPath) Modified = true; mPath = value; } } public string title { get { return mTitle; } set { if (value != mTitle) Modified = true; mTitle = value; } } public string ratio { get { return mRatio; } set { if (value != mRatio) Modified = true; mRatio = value; } } public int CompareTo(object obj) { alb_slide_class slide = obj as alb_slide_class; if (obj == null) return 1; if (sortdesc) return -(this.mPath.CompareTo(slide.mPath)); else return this.mPath.CompareTo(slide.mPath); } }
lesPersonnes.Where(p => p.Prenom.StartWith("P"))
lesPersonnes.OrderBy(p => p.Nom)
Select Naissance From Personnes Where Prenom = "Jean"
var lesJean = (from p in lesPersonnes where p.Prenom == "Jean" select new { p.Nom, p.DateNaissance } ).ToList();
List<string> nombres = new List<string> { "un", "deux", "trois" }; IEnumerable<string> tri = nombres.OrderBy(n => n); nombres.Add("quatre"); nombres.Add("cinq"); foreach (string n in tri) Console.WriteLine(n);
14 déc. 2017 à 20:00
Pour que Sort fonctionne, la classe doit implémenter IComparable, donc posséder la méthode CompareTo, comme MGD l’a vu.
Cette implémentation est la façon de faire historique. Elle presente cependant le défaut d’imposer une seule façon de trier, par exemple pour des gens, ce sera toujours le nom d’abord, le prenom ensuite et la date de naissance. Et quand tu veux trier par prénom c’est compliqué.
Avec linq et la méthode OrderBy, il n’est plus nécessaire d’implémenter IComparable et on définit la logique de tri quand on en a besoin.
Je tacherai de faire un exemple de chaque dans la soiree
15 déc. 2017 à 14:51
La méthode avec Linq et OrderBy est très intéressante à plus d'un point
1) plus court à écrire ( plus besoin de IComparable)
2) on peut changer le critère de tri quand on veut
3) plus besoin de .Reverse ( OrderByDescending fait le job )
Linq a encore de très beaux jours devant lui
Merci pour ce petit cours très instructif
Un bonjour à MGD Sofware en passant
15 déc. 2017 à 15:00
Modifié le 14 déc. 2017 à 22:30