SUPPRIMER UN ITEM DANS UN TABLEAU EN LE PARCOURANT UNE SEULE FOIS

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 18 août 2010 à 05:52
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 19 août 2010 à 09:02
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/52189-supprimer-un-item-dans-un-tableau-en-le-parcourant-une-seule-fois

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
19 août 2010 à 09:02
j'ajouterais concernant les Strings qu'il n'y as pas systematiquement de test a faire pour éviter les chaines vides...
tout dépend de ce à quoi l'on déstine le tableau...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
19 août 2010 à 09:00
quand je parles de compact, je veux dire de faire la recopie des elements renseignés dans le tableau, en laissant de coté les "cases" vides.
je ne parlais donc pas d'une fonction intégrée quelconque.

Il est possible de faire, donc, un CopyMemory pour décaler rapidement les données.
l'astuce consistera a ne pas redimensionner le tableau tout de suite, et de le faire plus tard (possible de conserver une variable contenant le nombre d'elements du tableau)

Mais bon, il faut bien cibler la problématique, ce n'est pas si courant que cela de devoir supprimer des items d'un tableau.
Khun Dun Messages postés 3 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2010
19 août 2010 à 08:58
le test supplémentaire prendra toujours moins de temps que les recopiages de tableaux ou encore l'utilisation parfois risquée d'un API

c'est garantit ! j'ai fais des tests de performance par rapport à ça, à cause d'un projet qui utilisait les tableaux de façon presque abusive ^^ le gain de temps est non négligeable
andalo Messages postés 102 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 20 octobre 2012
19 août 2010 à 08:53
je ne connaissais pas l'API copymemory, du coup j'ai trouvé ca :

http://www.vbfrance.com/forum/sujet-TABLEAUX-CHAINES-COPYMEMORY-QUAND-POTENCE-VOUS-GUETTE_1234952.aspx

la problématique est d'insérer une valeur mais ca se ressemble. Pour dire vrai j'avoue ne pas avoir pigé comment me servir de ces infos pour le moment.

faire un compact sur un tableau, ca non plus je ne connais pas, Renfield, si tu peux m'éclairer je suis preneur.

la méthode a Khun Dun est tentante. Mais je me demande si c'est si optimisé que ca. au moment de la suppression il n'y a pas photo. Mais au moment de la relecture du tableau, il faut ajouter un test supplémentaire à la lecture de chaque entrée. Le gain est il réel du coup?

Sehnsucht, effectivement il y a deux boucles, mais un seul parcours du tableau, il faut que je change le titre! peut tu expliquer cette ligne :
Dim index = Array.IndexOf(Of T)(source, toDelete)
et surtout a t'elle une équivalence en VB6?
si je comprend bien, elle te permet de retrouver l'index dans le tableau de la valeur a supprimer sans le parcourir.
Khun Dun Messages postés 3 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2010
19 août 2010 à 08:52
alors dans ce cas je créé un Type

Private Type tInfo
Value As Integer
Tag As Integer
End Type
Private mTableau(10) As tInfo 'on peut faire un tableau variable aussi

ensuite je remplie comme d'habitude mon tableau en utilisant Tableau(Index).Value = [integer]
et lorsque je souhaite effacer une valeur, je remplie le Tag avec par exemple -1
il suffit donc, quand on lit le tableau, de lire que les Tag différents de -1
Sehnsucht Messages postés 107 Date d'inscription samedi 25 novembre 2000 Statut Membre Dernière intervention 4 mai 2013
19 août 2010 à 01:09
C'est bien pour un tableau de String (ou autre type référence) mais pour un tableau d'Integer (ou autre type valeur) ?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
18 août 2010 à 23:56
j'approuve.

tout depend de l'usage...
ca evite de decaler les index...
et rien n'empeche de faire un Compact par la suite, pour recreer un tableau avec les valeurs non vides...
Khun Dun Messages postés 3 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2010
18 août 2010 à 23:27
moi j'ai une solution extrêmement simple et qui est nettement plus rapide comparée à ce qui est proposé ici, quand je veux supprimer une valeur de mon tableau je fais tableau(index)="" et quand j'ai besoin de lire mon tableau je ne lis que les valeurs différentes de "" tout simplement, sincèrement ça a l'air stupide comme ça, mais c'est ce qu'il y a de mieux pratiquement lorsqu'on a besoin d'optimisation
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
18 août 2010 à 19:01
Redim preserve ne fait pas obligatoirement de recopie... surtout dans le cas d'une reduction de taille.

l'exemple propose est en .Net, mais avec un CopyMemory, on peut arriver au meme code.
Sehnsucht Messages postés 107 Date d'inscription samedi 25 novembre 2000 Statut Membre Dernière intervention 4 mai 2013
18 août 2010 à 18:34
Je vois, malgré cela tu as quand même deux boucles même si la 2ème est imbriquée dans la 1ère, de plus le ReDim Preserve fais une copie de ton tableau en mémoire ce qui peut s'avérer lourd dans le cas d'un grand tableau.

Personnellement j'utilise une autre méthode, d'ailleurs je ne sais pas trop ce qu'elle vaut, si j'ai le temps je me ferais un petit benchmark mais je la poste ici des fois que...

Sub Remove(Of T)(ByRef source As T(), ByVal toDelete As T)
If source Is Nothing Then Exit Sub
Dim index = Array.IndexOf(Of T)(source, toDelete)
If index = -1 Then Exit Sub
Dim temp(source.Length - 2) As T
Array.ConstrainedCopy(source, 0, temp, 0, index)
Array.ConstrainedCopy(source, index + 1, temp, index, source.Length - index - 1)
source = temp
End Sub

Cordialement !
andalo Messages postés 102 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 20 octobre 2012
18 août 2010 à 15:03
Quand je me suis confronté au problème et que j'ai cherché sur ce site je n'ai trouvé que des solutions imposant de créer un deuxième tableau à remplir lors d'une première itération,et une deuxième itération pour re-remplir le premier tableau à partir du deuxième.Comme, pour une fois je me suis trouvé pas trop bête en faisant ca en une seule boucle, j'ai trouvé que ca optimisais un peu.
Sehnsucht Messages postés 107 Date d'inscription samedi 25 novembre 2000 Statut Membre Dernière intervention 4 mai 2013
18 août 2010 à 13:18
Bonjour,

Au risque de poser une question stupide (ça ne serait pas la première fois ^^),
en quoi ce code est-il optimisé (c'est une vraie question) ?

Cordialement !
andalo Messages postés 102 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 20 octobre 2012
18 août 2010 à 08:52
très juste, je corrige
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
18 août 2010 à 05:52
assures toi bien que ton tableau n'a pas qu'une seule entree...
Rejoignez-nous