Trier une arraylist

Résolu
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 - 25 janv. 2006 à 16:16
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 - 26 janv. 2006 à 11:28
Bonjour à tous,

J'ai une arraylist d'objet personne et je voudrais mettre en premier dans mon arraylist toutes les personnes qui ont le paramètre "nouveau = true", comment faire ? implementer l'interface Icomparer ? ben oui mais comment ? j'ai pas trouver

Par avance, merci.

14 réponses

MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
25 janv. 2006 à 19:42
> A quoi correspond this.nouveau ?
Tu as dis plus haut que tu avais un parametre "nouveau", c'est pour ca que j'ai utilisé "nouveau".
la ligne compare donc la variable nouveau de obj a la variable nouveu de l'objet courant.
j'aurais aussi pu mettre
<HR>
return
this.nouveau.CompareTo(((Personne)obj).nouveau);


<HR>
Mais a ce moment là, tu aurais eu un tri inverse (false en premier, true ensuite)

Si tu veux utiliser la méthode Personne.get_Nouveau() qui te ramene un bool, tu dois faire

<HR>
public int CompareTo(object obj)
{
return ((Personne)obj).get_Nouveau().CompareTo(this.get_Nouveau());
}


<HR>

Mais en C#, par convention on utilises des Propriétés plutot que des accesseurs (pas de méthode get_machin)

<HR>
private
bool nouveau;

public
bool Nouveau
{

get {
return
this.nouveau; }

//set { this.nouveau = value; } (enlever le commentaire si tu as besoins d'acceder a nouveau en ecriture)
}

public int CompareTo(object obj)
{
return ((Personne)obj).Nouveau.CompareTo(this.Nouveau);
}


<HR>

Mx
MVP C#
3
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 10:08
ben en faite avec public int CompareTo(object obj) il me met impossible d'instancier une classe abstraite ce qui n'est pas le cas avec
public int CompareTo(object obj, object obj2) et quand je fais :

return ((Personne)obj).get_Nouveau().CompareTo(this.get_Nouveau());

ca marche pas parceque CompareTo attend un object et non un bool....
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
26 janv. 2006 à 10:39
En fait, je suis parti du principe que tu n'utilisais pas IComparer, mais IComparable (et que tu l'implementais directement sur ta classe Personne, pas sur une classe "Sorter"
IComparer met en oeuvre la méthode Compare(object, object)
IComparable implement la méthode Compare(object)

et dans ce cas, tu peux utiliser liste_personne->Sort(); tout simplement, car personne implementant IComparable, le Sort va marcher tout seul.

Dis moi si ca peux marcher comme ca pour toi, sinon je vais voir avec IComparer


Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
26 janv. 2006 à 10:51
Tiens, voici un petit exemple avec IComparer


<HR>
using System;

using System.Collections;

using System.Text;

namespace ConsoleApplication1
{

class
Program
{

static
void Main(
string[] args)
{

ArrayList list =
new
ArrayList(4);
list.Add(
new
Personne(0,
true));
list.Add(
new
Personne(1,
false));
list.Add(
new
Personne(2,
false));
list.Add(
new
Personne(3,
true));
list.Add(
new
Personne(4,
true));
list.Sort(
new
Personne.
PersonneComparer());


foreach (
Personne p
in list)

Console.WriteLine(p.ToString());

Console.ReadLine();
}
}

public
class
Personne
{

private
int id;

private
bool nouveau;

public
int ID
{

get {
return
this.id; }
}

public
bool Nouveau
{

get {
return
this.nouveau; }
}


public Personne(
int id,
bool nouveau)
{

this.id = id;

this.nouveau = nouveau;
}


public
override
string ToString()
{

return
string.Format(
"Personne {0} ; Nouveau : {1}",
this.ID,
this.Nouveau);
}

public
class
PersonneComparer :
IComparer
{

public
int Compare(
object x,
object y)
{

Personne tempx = (
Personne)x;

Personne tempy = (
Personne)y;

return tempy.nouveau.CompareTo(tempx.nouveau);
}
}
}
}


<HR>


Mx
MVP C#
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
26 janv. 2006 à 11:15
C'est bizarre ca, que personne->get_Personne_Nouveau().CompareTo() attende un objet, dans la doc c'est bien marqué que bool.CompareTo peut attendre soit un objet, soit un bool.
J'ai malheureusement rien devant moi pour tester.

Pour ta méthode, si elle fonctionne, garde là. ;)
Ou sinon, plus proprement, tu pourrais implementer IComparable sur ta classe Personne, et utiliser personne1.CompareTo(personne2)


Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
26 janv. 2006 à 11:24
Y'a pas de quoi
Ah oui, pour tes conditions, pour que ce soit plus facile a lire, je mettrais :

if ((personne1->get_Personne_Nouveau() = = true) && (personne2->get_Personne_Nouveau() == false))
return -1 ; else if ((personne1->get_Personne_Nouveau() false) && (personne2->get_Personne_Nouveau() true))
return 1 ;
else return 0;


Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
25 janv. 2006 à 18:14
Bonjour,

Tu as juste a implémenter l'interface IComparable sur la classe Personne, et dans la méthode CompareTo:


<HR>
public
int CompareTo(
object obj)
{

return ((
Personne)obj).nouveau.CompareTo(
this.nouveau);
}

<HR>
Puis appeler la méthode Sort() de ton ArrayList

Si jamais tu es passé au .net 2, tu prefereas utiliser l'interface IComparable<T> pour éviter un Cast de l'objet

Mx
MVP C#
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
25 janv. 2006 à 18:58
Tout d'abord Merci de ta reponse, mais y'a un truc qui m'echappe :

public
int CompareTo(
object obj)
{

return ((
Personne)obj).nouveau.CompareTo(
this.nouveau);
}

je cast obj en personne, je fais
((
Personne)obj).get_Nouveau()..... mais après get_nouveau je me retrouver avec un bool et a quoi correspond this.nouveau ?

Par avance, merci.
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
26 janv. 2006 à 10:11
Est-ce qu'on pourrait entrevoir un bout de ta classe s'il te plait ?
Je pense que ce sera plus simple ;)



Mx
MVP C#
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 10:30
ben oui mais c'est du C++.Net mais c'est pareil tu va me dire:

public __gc class PersonneNouveauSorter : public IComparer
{

public :

PersonneNouveauSorter( Personne * personne_en_cours )
{
this->personne_en_cours = personne_en_cours ;
}

private : Personne* personne ;

public : int Compare(Object * x)
{

Personne* personne = dynamic_cast(x) ; // Je cast l'objet en personne

return personne->get_Personne_Nouveau().CompareTo(this->personne->get_Personne_Nouveau()) ; // marche pas car CompareTo attend un objet

}

};

Pour l'utiliser je fais :

liste_personne->Sort(new PersonneNouveauSorter(new Personne())) ; // mais il me marque impossible d'instancier une classe abstraite
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 11:07
Merci de ta réponse, le seul hic à priori c'est ici : return tempy.nouveau.CompareTo(tempx.nouveau); CompareTo attend un object et on lui passe un bool. J'ai essayer comme ca apparement ca marche : qu'en penses tu ? si le frais 1 à true et pas l'autre alors il passe devant sinon il passe derriere, enfin je crois

[Serializable]
public __gc class PersonneNouveauSorter : public IComparer
{

public :

PersonneNouveauSorter ( Personne * personne )
{
this->personne = personne ;
}

private : Personne * personne ;

public : int Compare(Object * x, Object * y)
{

Personne * personne1 = dynamic_cast(x) ;
Personne * personne2 = dynamic_cast(y) ;



if ((personne1->get_Personne_Nouveau()) && (personne2->get_Personne_Nouveau() == false))
return -1 ;

if ((personne1->get_Personne_Nouveau() == false) && (personne2->get_Personne_Nouveau()))
return 1 ;

return 0 ;
}
};
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 11:07
si la personne plutot
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 11:20
Oui c'est bizarre pourtant pour moi CompareTo je peux y mettre qu'un objet j'ai pas le choix mais c'est sur que ta méthode eu été bcp plus propre, merci de ton aide.
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
26 janv. 2006 à 11:28
ok ca roule
0
Rejoignez-nous