Page 1 sur 1
[Résolu] "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 14:21
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 ?
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 14:33
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.
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 15:52
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?
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 16:08
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?
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 17:38
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().
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 17:41
par djes
Oui, mais il a dit pour la 4.20, et je crois que listindex n'existait pas... (pas vérifié)
Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 18:34
par Anonyme
et la commande "continue" ??

Re: "DeleteElement" dans un "ForEach"
Publié : lun. 21/sept./2009 21:53
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
Re: "DeleteElement" dans un "ForEach"
Publié : mar. 22/sept./2009 5:47
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
Re: "DeleteElement" dans un "ForEach"
Publié : mar. 22/sept./2009 8:34
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.
Re: "DeleteElement" dans un "ForEach"
Publié : mar. 22/sept./2009 9:44
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...

)
Re: "DeleteElement" dans un "ForEach"
Publié : mar. 22/sept./2009 10:51
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.
