OVH Cloud OVH Cloud

For ... Each en partant de la fin ?

24 réponses
Avatar
Olivier
Bonjour


J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le dernier
?

Comme avant en faisant :
For i = mCol.Count - 1 To 0 Step -1



Merci
Olivier

10 réponses

1 2 3
Avatar
Patrick Philippot
Olivier wrote:
J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le
dernier ?



Bonjour,

A priori, j'ai 2 réponses immédiates qui me viennent à l'esprit:

1. Triez temporairement dans l'autre sens.

2. Dérivez une classe de votre collection de base et réimplémentez
l'interface IEnumerator de telle manière que IEnumerator.MoveNext fasse
plutôt un "MovePrevious" et que IEnumerator.Reset place la position
initiale "après le dernier élément" au lieu de "avant le premier
élément". Vive le polymorphisme!

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Olivier
Bon, vous allez me dire :

"Pourquoi tu tris pas à dans l'autre sens ?

Ben, parce que la collection que j'utilise n'a pas la méthode Sort()
C'est une collection typées qui hérite seulement de CollectionBase.

Olivier



"Olivier" <aa.aa.aa> a écrit dans le message de
news:
Bonjour


J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le


dernier
?

Comme avant en faisant :
For i = mCol.Count - 1 To 0 Step -1



Merci
Olivier




Avatar
Patrick Philippot
Olivier wrote:
"Pourquoi tu tris pas à dans l'autre sens ?

Ben, parce que la collection que j'utilise n'a pas la méthode Sort()
C'est une collection typées qui hérite seulement de CollectionBase.



Peut-être mais elle est triée quand même, non?

Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente l'interface
IComparable. Il suffit d'implémenter la méthode CompareTo de cette
interface de manière adéquate afin que les objets MaClasse soient triés
dans l'ordre que vous souhaitez.

Encore une fois, vive le polymorphisme! :-)

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Zoury
> Encore une fois, vive le polymorphisme! :-)



j'appuie la motion. :OD

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Olivier
Hum...

<<
Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente l'interface
IComparable. Il suffit d'implémenter la méthode CompareTo de cette
interface de manière adéquate afin que les objets MaClasse soient triés
dans l'ordre que vous souhaitez.







Franchement, j'ai pas tout compris, mais bon, je vais chercher un peu ce
soir...

Merci
Olivier



"Patrick Philippot" a écrit dans le
message de news:eoM$
Olivier wrote:
> "Pourquoi tu tris pas à dans l'autre sens ?
>
> Ben, parce que la collection que j'utilise n'a pas la méthode Sort()
> C'est une collection typées qui hérite seulement de CollectionBase.

Peut-être mais elle est triée quand même, non?

Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente l'interface
IComparable. Il suffit d'implémenter la méthode CompareTo de cette
interface de manière adéquate afin que les objets MaClasse soient triés
dans l'ordre que vous souhaitez.

Encore une fois, vive le polymorphisme! :-)

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr




Avatar
Patrick Philippot
Olivier wrote:
<<
Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente
l'interface IComparable. Il suffit d'implémenter la méthode CompareTo
de cette interface de manière adéquate afin que les objets MaClasse
soient triés dans l'ordre que vous souhaitez.





Franchement, j'ai pas tout compris, mais bon, je vais chercher un peu
ce soir...



Reprenons :-)

CollectionBase articule son fonctionnement sur une liste interne:
InnerList. Comme toutes les collections triées, InnerList vérifie si les
objets que l'on y stocke implémentent une interface appelée IComparable.
Si cette interface est implémentée par l'objet, c'est l'implémentation
de cette interface qui va être utilisée pour trier les objets. C'est la
méthode CompareTo (seule méthode de IComparable) qui permet de dire si
un objet est "plus grand" qu'un autre. Mais c'est chaque objet qui dit
lui-même s'il considère qu'il est plus grand ou plus petit qu'un autre
(dont on passe la référence en argument à CompareTo).

L'énoooooorme intérêt de cette approche polymorphique, c'est de
permettre à la collection de trier les objets en se basant sur des
informations fournies par les objets que l'on stocke dans la collection
plutôt que sur un algorithme lié à la collection elle-même.

En clair, cela signifie que ce sont les objets stockés dans la
collection qui savent comment ils doivent être triés. Le tri devient
donc dépendant de la nature de l'objet stocké plutôt que d'un mécanisme
interne. Si les objets stockés dans la collection implémentent
IComparable différemment, ils seront triés différemment.

N'est-ce pas un concept d'une suprême élégance?

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
\(\(Olivier\)\)
<<
Mais c'est chaque objet qui dit
lui-même s'il considère qu'il est plus grand ou plus petit qu'un autre






Justement c'est là, que je sais pas comment faire ?
Je crée un sub CompareTo ?
Je ne sais pas vraiment quoi mettre dedans ?

Ce soir, je préparerai un exemple simple, et si tu veux bien me montrer ?

Sinon, jusqu'a présent, je faisais dans MaClasse, une propriété en lecture
seule qui est une clé de tri de chaque objet, et je tri la dessus !
Bon, du genre Hastable mais sans utiliser hastable, je sais c'est bizarre
mais bon... par moment j'ai pas le temps de chercher et il faut aller vite,
vite.
C'est maintenant que j'ai un peu de temps et donc je cherche si je peux
"mieux" faire.

<<
N'est-ce pas un concept d'une suprême élégance?






Certe, mais j'attends de voir mon résultat final :-)
Car, l'élégance et la beauté sont des notions toutes relatives ;-)

Merci pour tes explications

Olivier


"Patrick Philippot" a écrit dans le
message de news:
Olivier wrote:
<<
Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente
l'interface IComparable. Il suffit d'implémenter la méthode CompareTo
de cette interface de manière adéquate afin que les objets MaClasse
soient triés dans l'ordre que vous souhaitez.





Franchement, j'ai pas tout compris, mais bon, je vais chercher un peu
ce soir...



Reprenons :-)

CollectionBase articule son fonctionnement sur une liste interne:
InnerList. Comme toutes les collections triées, InnerList vérifie si les
objets que l'on y stocke implémentent une interface appelée IComparable.
Si cette interface est implémentée par l'objet, c'est l'implémentation de
cette interface qui va être utilisée pour trier les objets. C'est la
méthode CompareTo (seule méthode de IComparable) qui permet de dire si un
objet est "plus grand" qu'un autre. Mais c'est chaque objet qui dit
lui-même s'il considère qu'il est plus grand ou plus petit qu'un autre
(dont on passe la référence en argument à CompareTo).

L'énoooooorme intérêt de cette approche polymorphique, c'est de permettre
à la collection de trier les objets en se basant sur des informations
fournies par les objets que l'on stocke dans la collection plutôt que sur
un algorithme lié à la collection elle-même.

En clair, cela signifie que ce sont les objets stockés dans la collection
qui savent comment ils doivent être triés. Le tri devient donc dépendant
de la nature de l'objet stocké plutôt que d'un mécanisme interne. Si les
objets stockés dans la collection implémentent IComparable différemment,
ils seront triés différemment.

N'est-ce pas un concept d'une suprême élégance?

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr



Avatar
Zim
Olivier a écrit :
Bon, vous allez me dire :

"Pourquoi tu tris pas à dans l'autre sens ?

Ben, parce que la collection que j'utilise n'a pas la méthode Sort()
C'est une collection typées qui hérite seulement de CollectionBase.

Olivier



"Olivier" <aa.aa.aa> a écrit dans le message de
news:

Bonjour


J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le



dernier

?

Comme avant en faisant :
For i = mCol.Count - 1 To 0 Step -1



Merci
Olivier









Salut Olivier,

Si ta collection ne possède pas de méthode Sort, à toi de la lui
implémentée.
Je te conseille de regarder toutes les docs sur les IComparer et la
méthode CompareTo.

En gros, ta collectionBase contient une arraylist protected (si je ne
dis pas de connerie) qui s'appelle InnerList. Cette dernière possède la
méthode Sort.
A toi d'ajouter à ta collection une méthode Sort qui appelle celle de
l'InnerList.
Bien entendu, il faut que l'innerlist sache comment la trier : c'est là
qu'intervient IComparer.
Cette interface ne comporte qu'une méthode int Compare(object x, object
y). Le int retour est la résultante d'un CompareTo de deux valeurs d'une
même propriété ou champs (enfin, généralement, c'est préférable).
C'est cette classe implémentant IComparer qui sera passée en paramètre
de la méthode Sort pour un tri idoine.

Un exemple vaut mieux qu'un long discours :

using System;
using System.Collections;

namespace ExempleTri
{
/// <summary>
/// La classe objet
/// </summary>
public class Personne
{
public string Nom, Prenom;
public int Age;

public Personne(string Nom, string Prenom, int Age)
{
this.Nom = Nom;
this.Prenom = Prenom;
this.Age = Age;
}
}

/// <summary>
/// Collection de personnes fortement typée
/// </summary>
public class CollectionPersonne : CollectionBase
{
public Personne this[int index]
{
get{return List[index] as Personne;}
set{List[index] = value;}
}

public int Add(Personne value)
{
return List.Add(value);
}

/// <summary>
/// Une méthode de tri par age. On appelle Sort de l'InnerList avec le
IComparer AgeComparer
/// </summary>
public void SortByAge()
{
InnerList.Sort(new AgeComparer());
}

/// <summary>
/// Une méthode de tri par nom (puis prénom). On passe cette fois le
NameComparer.
/// </summary>
public void SortByName()
{
InnerList.Sort(new NameComparer());
}

private class AgeComparer : IComparer
{
#region Membres de IComparer

public int Compare(object x, object y)
{
// Nos deux objet sont du même type
Personne pX = x as Personne;
Personne pY = y as Personne;

// et on renvoie le CompareTo des âges
return pX.Age.CompareTo(pY.Age);
}

#endregion
}

private class NameComparer : IComparer
{
#region Membres de IComparer

public int Compare(object x, object y)
{
Personne pX = x as Personne;
Personne pY = y as Personne;

int retour = pX.Nom.CompareTo(pY.Nom);
if(retour==0)
retour = pX.Prenom.CompareTo(pY.Prenom);

return retour;
}

#endregion
}
}

/// <summary>
/// Classe principale
/// </summary>
public class Principal
{
public static void Main()
{
Personne p1 = new Personne("Liguili", "Guy", 28);
Personne p2 = new Personne("Terieur", "Alain", 21);
Personne p3 = new Personne("Abitbol", "Georges", 35);
Personne p4 = new Personne("Terieur", "Alex", 33);

CollectionPersonne personnes = new CollectionPersonne();
personnes.Add(p1);
personnes.Add(p2);
personnes.Add(p3);
personnes.Add(p4);
//personnes.SortByAge();
personnes.SortByName();

foreach(Personne p in personnes)
{
Console.WriteLine("{0} {1} : {2} ans", p.Prenom, p.Nom, p.Age);
}

Console.Read();
}
}
}


En espérant avoir été assez clair.

Zim.
Avatar
\(\(Olivier\)\)
Ouaaaa !

Merci cela va beaucoup m'aider ... même si la syntaxe du c# est toujours
un regal pour moi :-(

Olivier


"Zim" <"r[omuald].szymanskiANTI"@SPAMlaposte.net> a écrit dans le message de
news:
Olivier a écrit :
Bon, vous allez me dire :

"Pourquoi tu tris pas à dans l'autre sens ?

Ben, parce que la collection que j'utilise n'a pas la méthode Sort()
C'est une collection typées qui hérite seulement de CollectionBase.

Olivier



"Olivier" <aa.aa.aa> a écrit dans le message de
news:

Bonjour


J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le



dernier

?

Comme avant en faisant :
For i = mCol.Count - 1 To 0 Step -1



Merci
Olivier









Salut Olivier,

Si ta collection ne possède pas de méthode Sort, à toi de la lui
implémentée.
Je te conseille de regarder toutes les docs sur les IComparer et la
méthode CompareTo.

En gros, ta collectionBase contient une arraylist protected (si je ne dis
pas de connerie) qui s'appelle InnerList. Cette dernière possède la
méthode Sort.
A toi d'ajouter à ta collection une méthode Sort qui appelle celle de
l'InnerList.
Bien entendu, il faut que l'innerlist sache comment la trier : c'est là
qu'intervient IComparer.
Cette interface ne comporte qu'une méthode int Compare(object x, object
y). Le int retour est la résultante d'un CompareTo de deux valeurs d'une
même propriété ou champs (enfin, généralement, c'est préférable).
C'est cette classe implémentant IComparer qui sera passée en paramètre de
la méthode Sort pour un tri idoine.

Un exemple vaut mieux qu'un long discours :

using System;
using System.Collections;

namespace ExempleTri
{
/// <summary>
/// La classe objet
/// </summary>
public class Personne
{
public string Nom, Prenom;
public int Age;

public Personne(string Nom, string Prenom, int Age)
{
this.Nom = Nom;
this.Prenom = Prenom;
this.Age = Age;
}
}

/// <summary>
/// Collection de personnes fortement typée
/// </summary>
public class CollectionPersonne : CollectionBase
{
public Personne this[int index]
{
get{return List[index] as Personne;}
set{List[index] = value;}
}

public int Add(Personne value)
{
return List.Add(value);
}

/// <summary>
/// Une méthode de tri par age. On appelle Sort de l'InnerList avec le
IComparer AgeComparer
/// </summary>
public void SortByAge()
{
InnerList.Sort(new AgeComparer());
}

/// <summary>
/// Une méthode de tri par nom (puis prénom). On passe cette fois le
NameComparer.
/// </summary>
public void SortByName()
{
InnerList.Sort(new NameComparer());
}

private class AgeComparer : IComparer
{
#region Membres de IComparer

public int Compare(object x, object y)
{
// Nos deux objet sont du même type
Personne pX = x as Personne;
Personne pY = y as Personne;

// et on renvoie le CompareTo des âges
return pX.Age.CompareTo(pY.Age);
}

#endregion
}

private class NameComparer : IComparer
{
#region Membres de IComparer

public int Compare(object x, object y)
{
Personne pX = x as Personne;
Personne pY = y as Personne;

int retour = pX.Nom.CompareTo(pY.Nom);
if(retour==0)
retour = pX.Prenom.CompareTo(pY.Prenom);

return retour;
}

#endregion
}
}

/// <summary>
/// Classe principale
/// </summary>
public class Principal
{
public static void Main()
{
Personne p1 = new Personne("Liguili", "Guy", 28);
Personne p2 = new Personne("Terieur", "Alain", 21);
Personne p3 = new Personne("Abitbol", "Georges", 35);
Personne p4 = new Personne("Terieur", "Alex", 33);

CollectionPersonne personnes = new CollectionPersonne();
personnes.Add(p1);
personnes.Add(p2);
personnes.Add(p3);
personnes.Add(p4);
//personnes.SortByAge();
personnes.SortByName();

foreach(Personne p in personnes)
{
Console.WriteLine("{0} {1} : {2} ans", p.Prenom, p.Nom, p.Age);
}

Console.Read();
}
}
}


En espérant avoir été assez clair.

Zim.


Avatar
Simon Mourier [MS]
Ca se discute; surtout en terme de performance. Trier une collection juste
pour la parcourir dans l'autre sens... euh...

Il me semble qu'il y a 2 cas de base:

* 1) on a le source de la collection. Si c'est basé sur un Array, ArrayList
ou autre Hashtable, on peut toujours se débrouiller pour soit
1a) exposer un IEnumerator inversé (proposition déjà faite)
1b) exposer un Count et un indexer (this[int index]) qui permet de faire un
for(...i--...)

* 2) on n'a pas le source de la collection. Il y a alors deux sous cas:
2a) la collection n'implémente que qu'IEnumerable et alors de toutes façons,
on ne peut pas la parcourir en partant de ... la fin, puisqu'à priori on ne
la connait pas (il pourrait y avoir 16123 millions d'enregistrements cachés
derrière tout ça :-)
2b) la collection implémente ICollection, et dans ce cas, on ne peut pas
forcément faire grand chose non plus puisqu'on ne connait que le nombre
(Count) mais on ne sait pas accéder à un élément à l'index I.
2c) la collection implémente IList et on peut faire un for(...i--...)

Simon.

"Patrick Philippot" a écrit dans le
message de news:
Olivier wrote:
<<
Supposons que vous stockiez des objets de type MaClasse dans cette
collection. Quand on appelle la méthode Sort de la InnerList de
CollectionBase, cette méthode vérifie si MaClasse implémente
l'interface IComparable. Il suffit d'implémenter la méthode CompareTo
de cette interface de manière adéquate afin que les objets MaClasse
soient triés dans l'ordre que vous souhaitez.





Franchement, j'ai pas tout compris, mais bon, je vais chercher un peu
ce soir...



Reprenons :-)

CollectionBase articule son fonctionnement sur une liste interne:
InnerList. Comme toutes les collections triées, InnerList vérifie si les
objets que l'on y stocke implémentent une interface appelée IComparable.
Si cette interface est implémentée par l'objet, c'est l'implémentation de
cette interface qui va être utilisée pour trier les objets. C'est la
méthode CompareTo (seule méthode de IComparable) qui permet de dire si un
objet est "plus grand" qu'un autre. Mais c'est chaque objet qui dit
lui-même s'il considère qu'il est plus grand ou plus petit qu'un autre
(dont on passe la référence en argument à CompareTo).

L'énoooooorme intérêt de cette approche polymorphique, c'est de permettre
à la collection de trier les objets en se basant sur des informations
fournies par les objets que l'on stocke dans la collection plutôt que sur
un algorithme lié à la collection elle-même.

En clair, cela signifie que ce sont les objets stockés dans la collection
qui savent comment ils doivent être triés. Le tri devient donc dépendant
de la nature de l'objet stocké plutôt que d'un mécanisme interne. Si les
objets stockés dans la collection implémentent IComparable différemment,
ils seront triés différemment.

N'est-ce pas un concept d'une suprême élégance?

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr



1 2 3