[Résolu] "DeleteElement" dans un "ForEach"

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

[Résolu] "DeleteElement" dans un "ForEach"

Message par kelebrindae »

Bonjour,

En 4.30, il y avait un truc qu'on n'avait pas le droit de faire:

Code : Tout sélectionner

; Définir une liste
Structure test_struct
  champ1.i
  champ2.s
EndStructure
Global Newlist test.test_struct()

; Remplir la liste
For i=1 to 20
  addElement(test())
  test()\champ1 = i
  test()\champ2 = "Coucou n°" + str(i)
Next i

; Parcours de la liste et suppression à la volée de certains éléments: Problème!
ForEach test()
  If test()\champ1 > 0 and test()\champ1 < 10 ; [EDIT: l'erreur ne se produisait que si on efface le premier élément de la liste]
    Debug "Suppression de l'élément n°"+Str(test()\champ1)
    deleteElement(test()) ; <= ici, on efface l'élément courant
  Else
    debug test()\champ2
  Endif
Next test()  ; <= du coup, ici, PB ne sait plus faire le "Next"
Je peux comprendre: si on efface l'élément courant, on ne peut plus faire Next parce que l'on n'a plus d'élément en ligne.
Pourtant, en 4.31, le code ci-dessus fonctionne (et très bien, apparemment; c'est d'ailleurs assez pratique).

Du coup, j'ai deux questions:
- Est-ce que je peux faire des "deleteElement" au milieu d'un "ForEach" sans risque que le code m'efface n'importe quoi, ou ne fonctionne plus à la prochaine version de PB?
- Comment vous faites, vous, pour effacer des éléments dans une liste en cours d'utilisation ?
Dernière modification par kelebrindae le mar. 22/sept./2009 9:45, modifié 3 fois.
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: "DeleteElement" dans un "ForEach"

Message par djes »

C'est dans la doc...
Comme la boucle se termine seulement lorsque le dernier élément de la liste est atteint (en terme de position), il est tout à fait possible de supprimer ou d' ajouter des éléments durant un cycle de boucle. De même il est permis de changer l'élément courant avec ChangeCurrentElement(). Après l'un de ces changements, le prochain cycle de boucle continue avec l'élément qui suit l'élément courant.
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: "DeleteElement" dans un "ForEach"

Message par kelebrindae »

Oui, mais il est également dit dans la doc de "deleteElement" que si l'on efface le premier élément de la liste, on se retrouve sans current element, à moins d'utiliser le flag optionnel 1; Or, cela ne semble pas se vérifier en v4.31.
=> le comportement de "deleteElement" a un peu changé en v4.31, d'où ma question.

Je veux dire: si comme moi, en 4.30 et avant, tu as déjà eu besoin de supprimer des éléments d'une liste à la volée, tu as probablement rencontré l'erreur "The linked list doesn't have a current element.", non ? Et dans ce cas, comment faisais-tu?
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: "DeleteElement" dans un "ForEach"

Message par djes »

Tu avais une erreur avec la 4.20 sur cette ligne là

Code : Tout sélectionner

Next test()  ; <= du coup, ici, PB ne sait plus faire le "Next"
c'est ça? Mais pourquoi ne mets tu pas "next" tout court?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: "DeleteElement" dans un "ForEach"

Message par Anonyme2 »

kelebrindae a écrit :Je veux dire: si comme moi, en 4.30 et avant, tu as déjà eu besoin de supprimer des éléments d'une liste à la volée, tu as probablement rencontré l'erreur "The linked list doesn't have a current element.", non ? Et dans ce cas, comment faisais-tu?
Pour avoir un code stable, tu dois tester s'il y a un un élément courant avec listindex()

La doc dit ceci pour Listindex
Valeur de retour

Un nombre indiquant la position actuelle de l'élément courant dans la liste. Le premier élément a la position 0, le deuxième la position 1, etc.. Une valeur de -1 indique qu'il n'y a pas d'élément courant (soit la liste est vide, soit les limites de la liste on été franchies à l'aide des commandes PreviousElement(), NextElement() ou ResetList().
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: "DeleteElement" dans un "ForEach"

Message par djes »

Oui, mais il a dit pour la 4.20, et je crois que listindex n'existait pas... (pas vérifié)
Anonyme

Re: "DeleteElement" dans un "ForEach"

Message par Anonyme »

et la commande "continue" ?? :mrgreen:
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: "DeleteElement" dans un "ForEach"

Message par Le Soldat Inconnu »

Je mets régulièrement des AddElement, DeleteElement dans une boucle ForEach et ça marche très bien

Juste que après un AddElement, il faut faire PreviousElement, sinon, le l'élément ajouté ne sera pas traité au prochain tour de boucle, on va le sauter
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: "DeleteElement" dans un "ForEach"

Message par Anonyme2 »

djes a écrit :Oui, mais il a dit pour la 4.20, et je crois que listindex n'existait pas... (pas vérifié)
ListIndex existait déjà avec la 4.10 (j'ai vérifié) et elle existait déjà avant je pense.

Pour effacer des éléments d'une liste, je scrute la liste à partir de la fin [c'est mon habitude car je fais la même chose avec les listIconGadget ce qui évite de modifier la position des éléments (utile si on scrute avec GetGadgetItemText) qui sont avant la position courante].

En scrutant par la fin, on peut faire

Code : Tout sélectionner

NewList a.l()

AddElement(a())
a() = 10
AddElement(a())
a() = 11
AddElement(a())
a() = 12
AddElement(a())
a() = 13
AddElement(a())
a() = 14
AddElement(a())
a() = 15




Element_courant = 1
If LastElement(a())
     Repeat
          If a() = 13
               DeleteElement(a())
               Element_courant = ListIndex(a())
               Debug "Element_courant = "+ Str(Element_courant)
          Else
               Element_courant = PreviousElement(a())
               If Element_courant = 0
                  Element_courant -1
               EndIf
               Debug "Element_courant = "+ Str(Element_courant)
          EndIf
     Until Element_courant = -1
EndIf

Debug ListSize(a())

Debug ListIndex(a())
Debug ""

ForEach a()
   Debug a()
Next
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: "DeleteElement" dans un "ForEach"

Message par djes »

Denis> Sympa comme petit truc! :)

Sinon moi ça dépend des cas, j'ai eu le problème dont tu parles une seule fois, que j'ai réglé avec le flag à '1'; il suffisait de bien réfléchir et la solution s'imposait.
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: "DeleteElement" dans un "ForEach"

Message par kelebrindae »

djes a écrit :il suffisait de bien réfléchir et la solution s'imposait.
Ouch, t'es dur, là; tu t'es levé du pied gauche ? :|

Pour le "Next test()", je conviens que ce n'est pas nécessaire, mais j'aime bien le mettre pour que le code soit plus explicite.

En tout cas, merci à tous pour vos réponses (sur un problème qui n'existe plus en 4.31, en plus... :wink: )
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: "DeleteElement" dans un "ForEach"

Message par djes »

kelebrindae a écrit :
djes a écrit :il suffisait de bien réfléchir et la solution s'imposait.
Ouch, t'es dur, là; tu t'es levé du pied gauche ? :|
Ouch, non je parlais de moi, j'ai mis ";", sinon je serais passé à la ligne. ;)
Répondre