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:
<<
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 ?



Bien. Je crois qu'il va vous falloir en premier lieu relire la doc sur
"comment implémenter une interface". Il me semble que c'est ce qui vous
manque pour bien comprendre tout ce que l'on vous raconte depuis le
début de ce thread. Si vous n'avez pas assimilé les notions d'interface,
de polymorphisme et d'implémentation d'une interface en C#, je crois que
nous sommes contre-productifs.

Voir "Interfaces et classes abstraites" dans la doc MSDN C# ou le
chapitre sur les interfaces de votre bouquin préféré sur C#.

Ne cherchez pas une recette à appliquer en aveugle sans comprendre les
concepts qui sont derrière. Si vous voulez faire de .Net (et de C#) un
outil de développement efficace, il est essentiel que vous compreniez
ces mécanismes fondamentaux. Inutile de tourner autour du pot. Et ce
n'est pas au travers d'un newsgroup que nous pourrons vous expliquer
tout ça clairement. Par contre, nous sommes là pour aider à comprendre
et répondre aux questions qui se poseraient pendant cette découverte.

Ne voyez pas dans ces propos une dérobade mais je crois qu'il faut
prendre les choses dans le bon ordre.

Je ne sais pas vraiment quoi mettre dedans ?



C'est décrit dans la doc de chaque méthode de chaque interface. La doc
de IComparable.CompareTo dit clairement que CompareTo reçoit en argument
la référence à un objet qui est à comparer à l'instance courante (la
référence de l'objet qui reçoit l'appel à CompareTo). Si l'objet qui
reçoit l'appel à CompareTo considère qu'il est plus grand que l'objet
passé en argument, il retourne une valeur > 0 ( plus petit, une valeur
plus petite que 0, égal, la valeur 0).

Exemple:

class MaClasse : IComparable
{
public int CompareTo(object obj)
{
... code qui compare this et obj et qui
retourne la valeur adéquate
}

... vos autres méthodes
}

----

Notez également qu'au cours de ce thread 2 approches différentes
concernant la modification du tri vous ont été proposées. A ne pas
confondre. La méthode dont nous parlons ci-dessus consiste à utiliser la
capacité de vos objets à implémenter l'interface IComparable. C'est à
mon avis la meilleure puisqu'elle est indépendante de la collection
elle-même.

Pour le tri d'objets n'implémentant pas IComparable, on se rabat sur
l'utilisation de l'interface IComparer qui permet de brancher sur la
collection un mécanisme de tri différent du mécanisme par défaut. Cette
méthode est démontrée dans la documentation de ArrayList.Sort.

Ce sont 2 manières complémentaires de traiter le problème qui répondent
à des contextes différents. Il est important de ne pas les confondre. La
méthode utilisée dépend de l'implémentation de ArrayList.Sort qui est
appelée (voir les différentes versions de cette méthode):

public virtual void Sort();
Trie les éléments de l'ArrayList en utilisant l'implémentation de
IComparable mise en oeuvre par chaque élément de la collection.

public virtual void Sort(IComparer);
Trie les éléments en utilisant l'objet comparateur passé en argument et
qui est supposé implémenter l'interface IComparer

public virtual void Sort(int, int, IComparer);
Idem mais pour un sous-ensemble des éléments.

Voir également ces exemples:
http://www.dotnetextreme.com/articles/IComparableInterface.asp

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Thierry Bertrand
C'est bizarre, mais j'avais appris qu'une boucle for peut toujours être
transformée en une boucle do while

For i= mCol.Count - 1 to 0 step -1

se tranforme simplement en

I=mCol.Count-1
do while i >=0
...
i=i-1
loop

me gourre-je ???


"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
Olivier
oui, mais c'est pas vraiment mon pb :-)

Merci
Olivier


"Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a écrit
dans le message de news:
C'est bizarre, mais j'avais appris qu'une boucle for peut toujours être
transformée en une boucle do while

For i= mCol.Count - 1 to 0 step -1

se tranforme simplement en

I=mCol.Count-1
do while i >=0
...
i=i-1
loop

me gourre-je ???


"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
Thierry Bertrand
Comprends pas ???

Tu demandes à parcourir un for each mais en sens inverse.
cela est strictement équivalent à prendre les éléments de ta collection
dans une boucle en les adressant directement par un index décroissant.

Où alors ton problème n'est pas contenu dans ta question.



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

oui, mais c'est pas vraiment mon pb :-)

Merci
Olivier


"Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a


écrit
dans le message de news:
> C'est bizarre, mais j'avais appris qu'une boucle for peut toujours être
> transformée en une boucle do while
>
> For i= mCol.Count - 1 to 0 step -1
>
> se tranforme simplement en
>
> I=mCol.Count-1
> do while i >=0
> ...
> i=i-1
> loop
>
> me gourre-je ???
>
>
> "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
Thierry Bertrand wrote:
Comprends pas ???

Tu demandes à parcourir un for each mais en sens inverse.
cela est strictement équivalent à prendre les éléments de ta
collection dans une boucle en les adressant directement par un index
décroissant.



Oui, dans le fond. En considérant que pour une ArrayList le temps
d'énumération via une boucle For + la méthode Item est rigoureusement
identique au temps d'énumération via For Each (j'ai testé sur plusieurs
dizaines de milliers d'éléments), la boucle suivante devrait faire
l'affaire:

Dim E As MaClasse
For i = MaCol.InnerList.Count - 1 To 0 Step -1
E = MaCol.InnerList.Item(i)
...
Next

C'est moins souple que les méthodes dont nous avons parlé précédemment
(si la méthode de tri doit changer, on est coincé) mais cela répond à la
question initiale.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Thierry Bertrand
Ouf, merci mon Dieu, j'ai cru que j'étais devenu un crétin débile en passant
de VB6 à .NET ;-)))


"Patrick Philippot" a écrit dans le
message de news: uy47eW#
Thierry Bertrand wrote:
> Comprends pas ???
>
> Tu demandes à parcourir un for each mais en sens inverse.
> cela est strictement équivalent à prendre les éléments de ta
> collection dans une boucle en les adressant directement par un index
> décroissant.

Oui, dans le fond. En considérant que pour une ArrayList le temps
d'énumération via une boucle For + la méthode Item est rigoureusement
identique au temps d'énumération via For Each (j'ai testé sur plusieurs
dizaines de milliers d'éléments), la boucle suivante devrait faire
l'affaire:

Dim E As MaClasse
For i = MaCol.InnerList.Count - 1 To 0 Step -1
E = MaCol.InnerList.Item(i)
...
Next

C'est moins souple que les méthodes dont nous avons parlé précédemment
(si la méthode de tri doit changer, on est coincé) mais cela répond à la
question initiale.

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




Avatar
Olivier
;-)


C'est exactement ce que je fais actuellement. Faute de mieux, avant d'avoir
ces excellentes discussions.
Ma question était certe un peu incomplete.
J'ai oublié de rajouter les mots :

"... actuellement je fais For i = Col.Count-1 To 0 Step -1 ....
comment faire la même chose avec un For Each..."

Merci à tous.

Olivier


"Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a écrit
dans le message de news:%239KPZK%
Comprends pas ???

Tu demandes à parcourir un for each mais en sens inverse.
cela est strictement équivalent à prendre les éléments de ta collection
dans une boucle en les adressant directement par un index décroissant.

Où alors ton problème n'est pas contenu dans ta question.



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

> oui, mais c'est pas vraiment mon pb :-)
>
> Merci
> Olivier
>
>
> "Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a
écrit
> dans le message de news:
> > C'est bizarre, mais j'avais appris qu'une boucle for peut toujours


être
> > transformée en une boucle do while
> >
> > For i= mCol.Count - 1 to 0 step -1
> >
> > se tranforme simplement en
> >
> > I=mCol.Count-1
> > do while i >=0
> > ...
> > i=i-1
> > loop
> >
> > me gourre-je ???
> >
> >
> > "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
Zazar
Bonsoir,

En considérant que pour une ArrayList le temps
d'énumération via une boucle For + la méthode Item est rigoureusement
identique au temps d'énumération via For Each (j'ai testé sur plusieurs
dizaines de milliers d'éléments),



C'est pas de chance, il aurait fallu tester sur peu d'éléments ou sur
beaucoup plus d'élements pour pouvoir constater la différence.
En gros :
foreach crée un objet => 1 création d'objet par boucle : sur beaucoup
d'éléments ça ne se voit pas.
A chaque itération, avec foreach il y a quelques petites comparaisons qui
sont faîtes : elles sont peu gourmandes et il faut donc plus que quelques
dizaines de milliers d'éléments pour constater une différence.
Le temps d'énumération en utilisant une boucle for est donc moins grand
qu'en utilisant une boucle foreach, même si ça n'a pas toujours un impact
significatif.


--
Zazar
Avatar
Patrick Philippot
Zazar wrote:
foreach crée un objet => 1 création d'objet par boucle : sur beaucoup
d'éléments ça ne se voit pas.



Si c'est le cas, je ne vois pas bien pourquoi c'est nécessaire: il
s'agit de récupérer une référence sur une objet qui a déjà été instancié
et de la stocker dans la variable qui sert à boucler. Pourquoi une
instanciation par boucle est-elle nécessaire?

En tous cas, je crois que l'inventaire complet a été fait. Il ne reste à
Olivier qu'à choisir.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Zazar
Patrick Philippot wrote:
Zazar wrote:
foreach crée un objet => 1 création d'objet par boucle : sur beaucoup
d'éléments ça ne se voit pas.



Si c'est le cas, je ne vois pas bien pourquoi c'est nécessaire: il
s'agit de récupérer une référence sur une objet qui a déjà été
instancié et de la stocker dans la variable qui sert à boucler.
Pourquoi une instanciation par boucle est-elle nécessaire?



Attention, par boucle je parle de toute l'exécution du bloc foreach ou du
bloc for, pas d'une seule itération. Elle n'a bien lieu qu'une fois, et
c'est pour ça que si vous faîtes un benchmark sur 10000 objets, ça passe
totalement inaperçu.
La création d'objet en question, c'est la création de l'enumerator.

--
Zazar
1 2 3