Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

tri tableau multi-dimension, plusieures clefs de tri

7 réponses
Avatar
cyrille
Bonjour,

En parcourant la doc de C# je n'ais trouv=E9 que des m=E9thodes toutes si=
mples de tri :
Array.Sort, ArrayList.Sort ...

Toutes sont uni-directionnelles et sur une seule clef.

Est-ce que j'ais loup=E9 quelque chose ?

Connaissez vous des classes qui offrent des fonctionnalit=E9s de tri un p=
eu =E9volu=E9es ?

Merci pour vos lumi=E8res,
cyrille

7 réponses

Avatar
Ambassadeur Kosh
> Connaissez vous des classes qui offrent des fonctionnalités de tri un peu
évoluées ?
Merci pour vos lumières,
cyrille



ben toutes : un ordre est un ordre.

tu passes le Comparer qui va bien et c'est fait

genre

int Compare(Client a,Client b)
{
int ordre1=a.Nom.Compare(b.Nom) ;
if(ordre1==0)
{
int ordre2=a.Prenom.Compare(b.Prenom) ;
return ordre2 ;
}
else
return ordre1 ;
}

apres, c'est vite fait de se fabriquer un CascadeComparer<T> qui possede une
collection de Comparer<T>... enfin voila quoi...
Avatar
Zazar
Bonjour,

En parcourant la doc de C# je n'ais trouvé que des méthodes toutes simples


de tri :
Array.Sort, ArrayList.Sort ...

Toutes sont uni-directionnelles



Non, elles sont unidirectionnelles par défaut. Libre à vous d'utiliser un
Comparer permettant le tri dans l'ordre que vous désirez.

et sur une seule clef.



Qu'est ce que vous entendez par là ?


Est-ce que j'ais loupé quelque chose ?



Oui, je pense que vous êtes passé à coté des interface IComparer et
IComparable. En gros, la méthode Sort fournit l'algorithme de tri, et vous ,
grâce à ces interfaces, vous choisissez comment comparer les différents
éléments de votre tableau.
Aprés si vous voulez choisir un autre algorithme de tri, vous devez
effectivement l'implémenter.


--
Zazar
Avatar
cyrille
Ambassadeur Kosh wrote:


ben toutes : un ordre est un ordre.

tu passes le Comparer qui va bien et c'est fait

genre

int Compare(Client a,Client b)
{
int ordre1=a.Nom.Compare(b.Nom) ;
if(ordre1==0)
{
int ordre2=a.Prenom.Compare(b.Prenom) ;
return ordre2 ;
}
else
return ordre1 ;
}



Merci ça m'a l'air sympa, je pars étudier ta solution ...

Comment fais tu pour que la signature de la méthode Compare soit diffé rente de Compare( Object x, Object y ) ?
Quand je fais ça, le compilo râle que la methode Compare de IComparer n'est pas implémentée ...

apres, c'est vite fait de se fabriquer un CascadeComparer<T> qui possed e une
collection de Comparer<T>... enfin voila quoi...



heu ... les <T> c'est bien les 'generics' du nouveau C# ?
je déjà utilisés les 'templates' du C++, mais avec C#, c'était de s lignes de codes ou du casting à n'en plus finir ;o{


cyrille
Avatar
Ambassadeur Kosh
> Comment fais tu pour que la signature de la méthode Compare soit
différente de Compare( Object x, Object y ) ?
Quand je fais ça, le compilo râle que la methode Compare de IComparer
n'est pas implémentée ...



tu n'es donc pas en 2005. alors en gros, procede de la sorte.

int IComparer.Compare(object x,object y)
{
Client a = (Client)x ;
Client b = (Client)y ;

return Compare(a,b) ;
}

public new int Compare(Client x,Client y)
{
...
}

apres, appuie toi sur le code generé par SharpDevelopp ou du code existant
de Reflector pour gerer correctement les null.

apres, c'est vite fait de se fabriquer un CascadeComparer<T> qui possede
une collection de Comparer<T>... enfin voila quoi...



heu ... les <T> c'est bien les 'generics' du nouveau C# ?
je déjà utilisés les 'templates' du C++, mais avec C#, c'était des lignes
de codes ou du casting à n'en plus finir ;o{



oui, mais bientot ton calvaire sera terminé :)
et quelque chose me dit que tu es passé à côté de concepts assez pratiques,
comme pour les collections par exemple. y'a moyen de pas caster...
Avatar
Ambassadeur Kosh
voila plus precisement la tronche d'un Compare

public int Compare(object a, object b)
{
if (a == b)
{
return 0;
}
if (a == null)
{
return -1;
}
if (b == null)
{
return 1;
}
// et la tu place la comparaison
Avatar
cyrille
Ambassadeur Kosh wrote:

et quelque chose me dit que tu es passé à côté de concepts asse z pratiques,
comme pour les collections par exemple. y'a moyen de pas caster...




haha ... je suis interpelé ;o)
peux tu développer ?

parce qu'à part écrire une méthode encapsulante pour chaque métho de de collection, j'ais pas trouvé comment éviter le
casting avec C# (VS.NET 2003).

chuis preneur d'idée et d'exemple !
cyrille
Avatar
Ambassadeur Kosh
ok

puisqu'on a pas de genricité, on ecrit soit meme la classe pour chaque type
parametre.
par contre, on peut forcer le foreach a n'accepter que des objets du type de
la collection. et pour remplacer la genericité, on genere : CodeSmith, Xml
Xslt... rien de bien méchant, mais bigrement pratique.

voila un code exemple pour une collection, à utiliser tel quel.

using System;
using System.Collections;

namespace Test
{
[Serializable()]
public class DummyCollection : CollectionBase {

public DummyCollection()
{
}

public DummyCollection(DummyCollection val)
{
this.AddRange(val);
}

public DummyCollection(Dummy[] val)
{
this.AddRange(val);
}

public Dummy this[int index] {
get {
return ((Dummy)(List[index]));
}
set {
List[index] = value;
}
}

public int Add(Dummy val)
{
return List.Add(val);
}

public void AddRange(Dummy[] val)
{
for (int i = 0; i < val.Length; i++) {
this.Add(val[i]);
}
}

public void AddRange(DummyCollection val)
{
for (int i = 0; i < val.Count; i++)
{
this.Add(val[i]);
}
}

public bool Contains(Dummy val)
{
return List.Contains(val);
}

public void CopyTo(Dummy[] array, int index)
{
List.CopyTo(array, index);
}

public int IndexOf(Dummy val)
{
return List.IndexOf(val);
}

public void Insert(int index, Dummy val)
{
List.Insert(index, val);
}

public new DummyEnumerator GetEnumerator()
{
return new DummyEnumerator(this);
}

public void Remove(Dummy val)
{
List.Remove(val);
}

public class DummyEnumerator : IEnumerator
{
IEnumerator baseEnumerator;
IEnumerable temp;

public DummyEnumerator(DummyCollection mappings)
{
this.temp = ((IEnumerable)(mappings));
this.baseEnumerator = temp.GetEnumerator();
}

public Dummy Current {
get {
return ((Dummy)(baseEnumerator.Current));
}
}

object IEnumerator.Current {
get {
return baseEnumerator.Current;
}
}

public bool MoveNext()
{
return baseEnumerator.MoveNext();
}

bool IEnumerator.MoveNext()
{
return baseEnumerator.MoveNext();
}

public void Reset()
{
baseEnumerator.Reset();
}

void IEnumerator.Reset()
{
baseEnumerator.Reset();
}
}
}
}