Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Comprendre les tableaux (Array)

Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par Nataly, le 27 mars 2010

array.jpg

Voici qui s'adresse à ceux que le mot tableau rebute. Extraits tous chauds du forum : “C'est peut-être un peu long, mais les tableaux je les fuis comme la peste” … “Ah oui, un tableau… Mais je débute, je n'y comprends rien !”

A ceux là, et à tous ceux qui s'y reconnaitront, je dis : trop dommage !

Les tableaux, c'est pratique et pas si difficile que ça, voire pas difficile du tout. Vous avez déjà croisé une commode dans votre vie ? Et quand on vous a dit “Va chercher dans le tiroir du haut”, vous y êtes arrivé que je sache ? Et ben voilà, vous savez utiliser les tableaux :)

Donc on peut commencer.

Pour démarrer : créer, remplir et lire

Ce qu'il faut savoir, c'est que dans un tableau on peut ranger ce qu'on veut (ou presque), des données de tous types : int, String, Booleen, Object, Shape, en passant par MovieClip et même des tableaux…

Un tableau en ActionScript (et un paquet d'autre langages ;-)), ça se dit Array

Et comme pour tous les objets, pour les utiliser encore faut il les créer.
Donc une variable tbEssai de type Array

var tbEssai:Array;

… qui vaut quoi ? un nouveau tableau :

var tbEssai:Array = new Array();

Nous voilà avec une commode vide, ou plus exactement, une commode sans tiroirs.
Ce qui est pratique, c'est que les tiroirs se fabriquent au fur et à mesure des besoins.
On ajoute un élément dans un tableau à l'aide de la méthode push.

tbEssai.push("Pierre");

…vous venez d'ajouter la chaine “Pierre” dans tbEssai.

tbEssai.push("Paul");

Qu'est ce que ça donne ? Regardons :

trace(tbEssai);
// Pierre,Paul
 
//Encore un…
tbEssai.push("Jacques");
trace(tbEssai);
// Pierre,Paul,Jacques
 
// plusieurs d'un coup :
tbEssai.push("Marie","Madeleine","Claude")
trace(tbEssai);
//Pierre,Paul,Jacques,Marie,Madeleine,Claude

J'ai introduit l'histoire en parlant de commode et de tiroirs mais on ne va pas bêtifier pendant trois pages non plus ;) donc :
Un tiroir, c'est un emplacement et un emplacement est identifié par un numéro d'index.
C'est pas plus dur que ça.
Ça donne : Pierre est au n° 0 (ah oui : on commence à zéro !), Paul au 1, et Jacques au 2.

Du coup, c'est tout niais d'aller lire ou récupérer l'élément de son choix dès lors qu'on connait son numéro d'index (et la syntaxe ;-))

On accède à un élément d'un tableau (lecture/écriture) avec la syntaxe à crochets, soit :

leTableau[n°Index]

var tbEssai:Array = new Array();
tbEssai.push("Pierre");
tbEssai.push("Paul");
tbEssai.push("Jacques");
 
// lecture :
trace(tbEssai[0]);
// Pierre
 
// écriture :
tbEssai[0]="Manon"; 
trace(tbEssai);
// Manon,Paul,Jacques

Jusque là, ça va ? ;)

L'autre truc utile qu'on connait par cœur, c'est la propriété length qui renvoie le nombre d'éléments du tableau.
Attention : pas l'index du dernier.
ici, tbEssai.length renvoie 3 mais Jacques (le dernier) est en 2. On commence à zéro… souvenez vous…

Exemple 1 : J'ai perdu mes clips

Bon, et bien avec cette poignée d'outils, déjà, on a tout pour répondre à celles et ceux qui sont là parce qu'ils ont “perdu les clips dans une boucle”. 8-)

Imaginons la consigne simple suivante (on va pas non plus se faire dactylo tout de suite) :

On veut créer 10 instances depuis un symbole de bibliothèque, puis dans un premier temps, n'afficher (addChild) que le premier. Si vous voulez jouer, construisez un clip minimaliste dans la bibliothèque, un rectangle et un champ texte dynamique txt (on va les numéroter au passage pour y voir clair). Nommez ce clip Elt et cochez la case exporter pour actionScript.

Mauvaise technique

for (var i=0; i<10; i++) {
       // créer nouvelle instance de Elt
	var clip:Elt=new Elt();
       // Numéroter
	clip.txt.text=String(i);
} 
// Ajouter à la liste d'affichage
addChild(clip);
clip.x=clip.y=150

C'est le clip 9 qui s'affiche, pas le 0 :!:
Normal :

A chaque tour de boucle la variable clip référence un nouveau clip (new), et forcément, le précédent est perdu :(
Disons le autrement : une variable c'est une ficelle accrochée à une donnée (objet, valeur), je tire la ficelle, je chope la donnée ou l'objet. Ici à chaque tour de boucle on détache la ficelle du précédent clip et on l'accroche au suivant… Si on détache le chien de sa laisse, il se sauve et on pourra toujours courir.
Donc là, on a une laisse pour dix chiens, ça en fait neuf dans la nature. :mrgreen:
Comment faire ?
Tiens, filons la métaphore : les chiens pour ne pas les perdre, on va les ranger à la niche, au fur et à mesure de leur création. En l'espèce, la niche c'est un tableau.

// Un tableau
var tbElt:Array= new Array();
for (var i=0; i<10; i++) {
	var clip:Elt=new Elt();
	clip.txt.text=String(i);
        // Ranger le clip dans un tableau
	tbElt.push(clip);
}
// Ajouter le clip "rangé" au numéro d'index 0 du tableau
addChild(tbElt[0]);
tbElt[0].x=tbElt[0].y=150

Pas très fin d'appeler trois fois tbElt[0], c'est juste pour qu'on soit bien d'accord sur le fait que la syntaxe crochets renvoie une référence à ce qui est stocké au numéro d'index, utilisable comme tel.

En plus mieux :

var tbElt:Array= new Array();
for (var i=0; i<10; i++) {
	var clip:Elt=new Elt();
	clip.txt.text=String(i);
	tbElt.push(clip);
}
// pour changer, on affiche le n° 4
var leClip:MovieClip=tbElt[4]
addChild(leClip);
leClip.x=leClip.y=150


Profitez de cet exemple pour vous convaincre, et vous souvenir, qu'on met bel et bien ce qu'on veut dans un tableau, y compris des clips ; pas seulement des noms de clips sous forme de chaine, non non, le clip lui même tout entier avec toutes ses méthodes et propriétés.



Autres possibilités de création

Jusque là on sait :

créer un tableau : monTableau = new Array()
remplir un tableau monTableau.push(…)
lire et écrire dans un tableau monTableau[…]
compter le nombre d'éléments dans un tableau : monTableau.length

Pour créer un tableau, il y a d'autres techniques. On peut déclarer et valoriser le tableau, “d'un coup”.

var monTableau:Array=new Array("Pierre","Paul","Jacques");
var tbCoordonnéesX:Array=new Array(50,70,75,125,130);

Il suffit de passer, entre parenthèses et séparés par une virgule, les différents éléments du tableau.
Les éléments peuvent être de types différents.

var tb1:Array= new Array(50,-12,100,0.5,"25",true);

Notez cependant que tous les “nombres” seront typés Number :

for (var i:int=0; i<T1.length; i++) {
   trace(T1[i]);
   trace("-->" + typeof T1[i]);
}
50
-->number
-12
-->number
100
-->number
0.5
-->number
25
-->string
true
-->boolean

Et enfin, on peut se passer du 'new Array' et écrire tout bonnement :

var leTableau:Array=["un truc","un autre",18,false]
Notez bien l'emploi de crochets (et non de parenthèses comme avec la syntaxe new Array(…))

Attention ! Piège…

Il pourrait se produire qu'un jour on ait l'idée de créer un tableau avec une seule entrée, pour commencer, avec le projet de le remplir par la suite. Par exemple :

 
var tbEssai:Array= new Array("Pierre");
// […] 
// un peu plus tard :
tbEssai.push("Paul"); 
tbEssai.push("Jacques"); 
trace(tbEssai);
Pierre,Paul,Jacques

Avec des int maintenant :

var tbEssaiInt:Array= new Array(5);
// un peu plus tard :
tbEssaiInt.push(18);
tbEssaiInt.push(22);
trace(tbEssaiInt);
,,,,,18,22

Ah bah zutalors !

Hé oui, c'est une autre façon de créer un tableau :

var tb:Array= new Array(Taille);

On lui assigne une taille, mais les entrées sont vides.
En vrai c'est ce qu'on fait avec la toute première technique (constructeur on dit). Quand on écrit :

monTableau = new Array();

On crée un tableau de taille 0.
la doc le dit :

public function Array(numElements:int = 0)

Comprendre : numElements est de type int et vaut 0 par défaut (si on ne le renseigne pas)

Un tableau depuis un chaîne de caractères

Une dernière chose : vous pouvez obtenir un tableau de chaines (String) en utilisant la méthode split de la classe String.
En français : si vous appliquez la méthode split à une chaine de caractères (en lui passant un séparateur) vous obtiendrez un tableau. par exemple :

var lesNoms:String="Pierre#Paul#Jacques"
var tbNoms:Array= lesNoms.split("#")
trace(tbNoms)
var lesJours:String="lundi mardi mercredi jeudi vendredi samedi dimanche"
var tbJours:Array= lesJours.split(" ")
trace(tbJours)
 
Pierre,Paul,Jacques
lundi,mardi,mercredi,jeudi,vendredi,samedi,dimanche

On se résume

:arrow: Pour créer un tableau deux constructeurs possibles :

• Avec un nombre spécifié d'éléments
public function Array(numElements:int = 0)

var tb:Array= new Array(6);// six emplacements vides


• Avec des valeurs (séparées par des virgules)
public function Array(… values)

var monTableau:Array=new Array("Pierre","Paul","Jacques");


… et un “raccourci” : directement avec des crochets sans le mot new.

var leTableau:Array=["un truc","un autre",18,false]


On peut aussi utiliser la méthode split(…) sur une chaine.


:arrow: Ajouter : push(…)
:arrow: Lecture écriture : tb[…]
:arrow: Taille : length

Si arrivé là, vous vous dites : “Et bien, rien de bien sorcier là dedans…”, sachez que le reste est de la même eau :)

Lire les tableaux

join

Tout de suite, et puisque nous venons de parler de la méthode split qui renvoie un tableau depuis une chaine, voyons immédiatement la méthode qui fait le contraire, à savoir renvoyer une chaine depuis un tableau.

Il s'agit donc de la méthode join à qui on passe comme paramètre un caractère qui séparera les éléments de la chaine.

var tbEssai:Array=new Array("Madeleine","Valérie","Sophie","Pierre");
var laChaine:String=tbEssai.join(" et ");
trace(laChaine);
Madeleine et Valérie et Sophie et Pierre

Oui… Je dis un caractère et j'exemplifie à l'aide d'une chaine… je sais mais c'était trop compliqué à formuler 8-)
En vrai de vrai, on peut passer n'importe quoi comme séparateur, une chaine, un int, de l'objet… ce qu'on veut. Le séparateur sera au passage converti en chaine ;)

indexOf / lastIndexOf

Ou, comment retrouver le numéro d'index d'un élément de tableau… Maintenant que vous avez apprivoisé l'animal tableau, certainement mes commentaires sont-ils superflus. Les noms des méthodes parlent d'eux même, pour peu qu'on ait quelques notions d'anglais (…mais quand même : indexDe, dernierIndexDe… même moi je me passe de dico ;) ) :

var tbEssai:Array= new Array("Madeleine","Valérie","Sophie","Pierre","Anne","Denise","Madeleine","Bertrand");
trace(tbEssai.indexOf("Sophie"))
//--> 2
trace(tbEssai.lastIndexOf("Madeleine"))
//--> 6
trace(tbEssai.indexOf("Madeleine"))
//--> 0
trace(tbEssai.lastIndexOf("Portnawak"))
//--> -1
trace(tbEssai.indexOf("Portnawak"))
//--> -1

Ces quelques lignes permettent de préciser les choses :
indexOf, renvoie le premier numéro d'index correspondant à l'élément spécifié.
lastIndexOf, renvoie le dernier numéro d'index correspondant à l'élément spécifié.

Si aucune correspondance n'est trouvée, c'est -1 qui est renvoyé, pour l'une comme l'autre (méthode ;))

Exemple 2 : je veux traduire une date

:idea: Tiens, histoire de se détendre :
On disait qu'on trainait sur le forum Mediabox et que l'on rencontrait cette question : Je voudrais traduire des noms de mois d'anglais en français…
Plusieurs pistes sont proposées, dont un switch qui vous semble vraiment excessif :

switch(month) {
                case "January" :
                month = "janvier"
                break;
                case "February" :
                month = "février"
                break;
                case "March" :
                month = "mars"
//etc...

Je vous laisse chercher une solution plus élégante ? (avec des jours, ce sera moins de dactylo… ;))
Indice, :mrgreen: voici les tableaux :

var tbJoursAng:Array= new Array("Monday","Tuesday","Wenesday","Thursday","Friday","Saturday","Sunday");
var tbJoursFr:Array= new Array("Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche");

A vous de jouer ! Oui : c'est à base d'indexOf… ;)

var idxJourAnglais:int=tbJoursAng.indexOf("Tuesday")
trace(tbJoursFr[idxJourAnglais])




Manipuler les tableaux

Parfait, maintenant que je vous sens bien en jambes, allons y pour un premier ensemble de méthodes qui nous permettront de jongler avec les éléments des tableaux.

Trier

Quand on trie un tableau ce dernier est modifié afin de refléter l'ordre de tri.

sort

Si vous souhaitez réorganiser les éléments d'un tableau selon leur valeur, vous utiliserez la méthode sort(…).
Utilisée sans arguments, le tri se fera selon les critères suivants :

• la casse (Majuscule précède minuscules)
• ordre alphabétique ascendant (a précède b)

var tb:Array= new Array("Paris","Lyon","marseille","bordeaux");
tb.sort();
trace(tb);
Lyon,Paris,bordeaux,marseille

Attention
Dans ce cas (sans arguments) quelque soit le type de données des éléments, ils seront triés comme s'il s'agissait de chaînes.

Ainsi, 200 est-il traité comme “200”, 3 comme “3”, 10 comme “10”… En conséquence 200 sera placé avant 3 mais après 10 ! :-o

var tb:Array=new Array(350,10,3,200);
tb.sort();
trace(tb);
10,200,3,350

Heureusement pour nous, des arguments sont prévus pour préciser les conditions de tri, :) ce sont des constantes que voici :

• Array.CASEINSENSITIVE (insensible à la case)
• Array.DESCENDING (décroissant)
• Array.NUMERIC (numérique)

var tb:Array= new Array("Paris","Lyon","marseille","bordeaux");
tb.sort(Array.CASEINSENSITIVE);
trace(tb);
bordeaux,Lyon,marseille,Paris
var tb:Array= new Array("Paris","Lyon","marseille","bordeaux");
tb.sort(Array.CASEINSENSITIVE | Array.DESCENDING);
trace(tb);
Paris,marseille,Lyon,bordeaux

Notez le caractère “|” pour utiliser plusieurs options.

var tb:Array=new Array(350,10,3,200);
tb.sort(Array.NUMERIC);
trace(tb);

A Noter :
Les éléments dont les valeurs sont identiques seront placés consécutivement.

Si vous souhaitez intercepter les cas de doublons vous utiliserez :

• Array.UNIQUESORT ()

Si il y a doublons, le tableau ne sera pas trié, et la méthode renvoie 0, dans le cas contraire elle renvoie le tableau trié (et le trie… ;))

var tb:Array=new Array(350,10,3,200,10);
 
var r:*=tb.sort(Array.NUMERIC | Array.UNIQUESORT);
trace("renvoie "+r);
trace("r==0 "+(r==0));
trace("tb = " +tb);
 
if (r==0) {
	trace("doublons");
}
renvoie 0
r==0 true
tb = 350,10,3,200,10
doublons
var tb:Array=new Array(350,10,3,200,100);
 
var r:*=tb.sort(Array.NUMERIC | Array.UNIQUESORT);
trace("renvoie "+r);
trace("r==0 "+(r==0));
trace("tb = " +tb);
 
if (r==0) {
	trace("doublons");
}
renvoie 3,10,100,200,350
r==0 false
tb = 3,10,100,200,350

• Array.RETURNINDEXEDARRAY

Avec cette option le tableau n'est pas modifié… mais la méthode renvoie un tableau qui reflète les résultats du tri avec les index d'origine :

var tb:Array=new Array("Claude","Anne","Denise","Bertrand");
trace(tb.sort(Array.RETURNINDEXEDARRAY));
1,3,0,2


sortOn

Cette méthode est très proche de sort, à la nuance près qu'elle trie “sur”…
sur quoi ?
sur un champ.

Je m'explique : On a vu que dans un tableau on pouvait mettre ce qu'on veut et notamment des objets (ce qui tombe bien pour un langage orienté objet ;)).

Ça ne mange pas de pain de vérifier

// un objet
var oMembre:Object;
// on le valorise
oMembre={nom:"Durand",prenom:"Pierre",age:28};
// on lit la propriété nom de oMembre
trace(oMembre.nom);
// --> Durand
// l'objet dans un tableau
var tbMembres:Array=new Array(oMembre);
// lire la propriété 'nom' de l'objet à l'index 0
trace(tbMembres[0].nom);
// --> Durand

Imaginons un tableau de membres, le trier, c'est gentil, mais en fonction de quoi ? C'est là qu'on dégaine sortOn :) et on lui passe une chaine qui vaut la propriété sur laquelle on souhaite trier. Dans ce cas, on parlera de champ.

Ajoutez donc deux membres :

tbMembres.push({nom:"Martin",prenom:"Paul",age:30});
tbMembres.push({nom:"Leroy",prenom:"Jacques",age:19});

On se propose de les trier sur les prénoms :

tbMembres.sortOn("prenom");
for (var i=0; i<tbMembres.length; i++) {
	trace(tbMembres[i].nom+" "+tbMembres[i].prenom+"  "+tbMembres[i].age);
}
Leroy Jacques  19
Martin Paul  30
Durand Pierre  28

Et sur l'âge ?
A vous de jouer :)

On attend :

Leroy Jacques  19
Durand Pierre  28
Martin Paul  30
tbMembres.sortOn("age", Array.NUMERIC);
for (var i=0; i<tbMembres.length; i++) {
	trace(tbMembres[i].nom+" "+tbMembres[i].prenom+"  "+tbMembres[i].age);
}

Bon, d'accord je l'ai pas dit : on dispose des mêmes options de tri qu'avec la méthode sort. Vous vous êtes fait ruser, vous avez oublié Array.NUMERIC ? Chic, vous vous en souviendrez ;-)

Du coup pas grand chose à ajouter : pour les options de tri, reportez vous à la méthode sort (ou à la doc ;-)).
Précisons quand même que les clips étant des objets vous pouvez, par conséquent, trier un tableau de clips selon n'importe quelle propriété des clips.
tbClips.sortOn(“x”,Array.Numeric);


reverse

Pour finir, reverse inverse l'ordre des éléments d'un tableau, rien à en dire.

var tb:Array= new Array("Machin",true,18,false);
var tbEnvers:Array=tb.reverse()
trace(tbEnvers);
false,18,true,Machin



Ajouter / Supprimer

Pour en finir avec push

On sait déjà ajouter à l'aide de la méthode push qui ajoute en fin de tableau. Il se trouve qu'elle renvoie au passage la nouvelle taille. Ça peut être pratique :

var max:int=tbQuelconque.push()
// pas utile d'aller chercher tbQuelconque.length, push renvoie la taille ;-)
for (var i:int=0;i<max;i++) {
	//traitements
}


unshift

La copine c'est unshift, qui ajoute un (ou plusieurs) élément(s) au début d'un tableau, et renvoie tout pareil la taille du tableau.

var tbEssai:Array= new Array("Marie","Madeleine","Claude");
tbEssai.unshift("Pierre","Paul")
trace(tbEssai);
Pierre,Paul,Marie,Madeleine,Claude


splice

Pour faire la transition entre les méthodes qui ajoutent et celles qui suppriment, voici splice qui ajoute et/ou supprime depuis un index spécifié - index compris.

splice(startIndex:int, deleteCount:uint, … values):Array

Elle attend
startIndex un numéro d'index, c'est là qu'on commence.
deleteCount combien d'éléments concernés par la suppression

     0 : pour aucune suppression
     rien : tout supprimer jusqu'à la fin

value : le ou les élément(s) à ajouter

Ajouter Marie entre Pierre et Paul

var tbEssai:Array= new Array("Pierre","Paul","Jacques");
 
// Ça se passe index 1, on ne supprime rien du tout, on ajoute "Marie"
tbEssai.splice(1,0,"Marie")
trace(tbEssai);
Pierre,Marie,Paul,Jacques

Ajouter Madeleine et Claude entre Marie et Paul

// Ça se passe index 2, on ne supprime rien du tout, on ajoute "Madeleine","Claude"
tbEssai.splice(2,0,"Madeleine","Claude")
trace(tbEssai);
Pierre,Marie,Madeleine,Claude,Paul,Jacques

Remplacer Claude par Valérie

// index 3, on supprime un élément (Claude), on ajoute (remplace donc par) "Valérie"
tbEssai.splice(3,1,"Valérie")
trace(tbEssai);
Pierre,Marie,Madeleine,Valérie,Paul,Jacques

Supprimer Marie, Madeleine et Valérie (et les récupérer)

// index 1, on supprime trois éléments (depuis 1 inclus)
var tbRecup:Array=tbEssai.splice(1,3)
trace(tbEssai);
//--> Pierre,Paul,Jacques
trace(tbRecup);
//--> Marie,Madeleine,Valérie

Comme illustré ci-dessus, splice renvoie un tableau des éléments supprimés.


pop et shift

Ces deux méthodes suppriment un élément (et renvoient l'élément supprimé).
pop supprime à la fin, shift au début.

Supprime dernier, pop :

var tbEssai:Array= new Array("Pierre","Paul","Jacques");
var nom:String=tbEssai.pop()
trace(tbEssai);
//--> Pierre,Paul
trace(nom)
//--> Jacques

Supprime premier, shift :

var tbEssai:Array= new Array("Pierre","Paul","Jacques");
var nom:String=tbEssai.shift()
trace(tbEssai);
//--> Paul,Jacques
trace(nom)
//--> Pierre


Mélanger

[edit Nataly 26/02/2013]

La classe Array ne nous donne pas de méthode spécifique pour mélanger les entrées d'un tableau, il faut le faire à l'huile de phalanges.
Il y a quantité de façons de s'y prendre, plus ou moins gourmandes. Badwolf propose dans cette conversation une technique très performante, (ne vous privez pas de lire les messages suivants)



Créer un nouveau tableau

concat

Concatène (mélange) deux tableaux en un.

var tbNouveau:Array=tb1.concat(tb2)

var tbGarcons:Array= new Array("Pierre","Paul","Jacques");
var tbFilles:Array= new Array("Madeleine","Valérie","Sophie");
var tabGarconsFilles:Array=tbGarcons.concat(tbFilles)
trace(tabGarconsFilles);
Pierre,Paul,Jacques,Madeleine,Valérie,Sophie
var tbGarcons:Array= new Array("Pierre","Paul","Jacques");
var tbFilles:Array= new Array("Madeleine","Valérie","Sophie");
var tabGarconsBool:Array=tbGarcons.concat(true,false,false)
trace(tabGarconsBool);
Pierre,Paul,Jacques,true,false,false


slice

Renvoie un nouveau tableau à partir d'une sélection d'éléments sans modifier le tableau d'origine.

slice(startIndex:int = 0, endIndex:int = 16777215):Array

On lui passe un index de départ qui sera inclus dans le nouveau tableau et un index d'arrivée, qui sera exclu.

var tbEssai:Array= new Array("Madeleine","Valérie","Sophie","Pierre","Anne","Denise","Bertrand");
// on veux Valérie,Sophie,Pierre
// de Valérie (1) à Anne Exclue (4)
var tbNouveau:Array=tbEssai.slice(1,4)
trace(tbNouveau)
Valérie,Sophie,Pierre

Sans index d'arrivée, on prend tout depuis l'index de départ

var tbEssai:Array= new Array("Madeleine","Valérie","Sophie","Pierre","Anne","Denise","Bertrand");
var tbNouveau:Array=tbEssai.slice(1)
trace(tbNouveau)
Valérie,Sophie,Pierre,Anne,Denise,Bertrand

Avec un index de départ négatif, on compte depuis la fin du tableau avec -1 pour le dernier élément. Ici Anne est en -3.

Avec un index d'arrivée négatif, pareil : on compte depuis la fin avec -1 pour le dernier élément.

par exemple Valérie,Sophie,Pierre mais en partant de la fin

var tbEssai:Array= new Array("Madeleine","Valérie","Sophie","Pierre","Anne","Denise","Bertrand");
// on veux Valérie,Sophie,Pierre
// de Valérie (-6) à Anne Exclue (-3)
var tbNouveau:Array=tbEssai.slice(-6,-3)
trace(tbNouveau)
Valérie,Sophie,Pierre


sans paramètres

Là, je me permets d'attirer votre attention, si d'aventure ce long exposé un peu soporifique vous a engourdis, c'est le moment de vous secouer du neuronne ;)

Quand on ne passe pas d'argument à slice on obtient une copie du tableau :

var tbA:Array= new Array(15,30,50,20);
var tbB:Array= tbA.slice()
trace("tbA : "+tbA+"\ntbB : "+tbB)
tbA : 15,30,50,20
tbB : 15,30,50,20

Oui, oh ! La belle affaire…
J'en entends maugréer qu'il n'y avait pas de quoi se réveiller pour si peu, d'autant qu'on aurait tout aussi bien pu écrire :

var tbB:Array= tbA;

Oui… Mais non. ;-)

Une chose importante à savoir en ce qui concerne les tableaux, c'est que les éléments y sont stockés par référence, et non par valeur.
Quand j'écris tbEssai[0]=2; flashPlayer se souviendra, non pas de la valeur 2, mais de l'endroit où '2' a été écrit (en mémoire). Ce n'est pas la valeur de l'élément qui est mémorisée mais son adresse (référence). En conséquence, regardons ce qui se passe avec la syntaxe tbA=tbB :

var tbA:Array=new Array(15,30,50,20);
// On crée un nouveau tableau qui est le même que tbA 
var tbB:Array=tbA;
trace("tbA : "+tbA+"\ntbB : "+tbB);
//--> tbA : 15,30,50,20
//--> tbB : 15,30,50,20
// On modifie tbA[0]
tbA[0]=700;
trace("tbA : "+tbA+"\ntbB : "+tbB);
//--> tbA : 700,30,50,20
//--> tbB : 700,30,50,20

Zut ! tbB[0] est lui aussi modifié ! 8-O

Normal j'avais prévenu : par référence ;-)
tbB = tbA, ça implique que tbB stocke non pas les mêmes valeurs que tbA, mais les mêmes références que tbA. Il pointe sur les mêmes adresses mémoire…
Quand on écrit dans tbA[0], flashPlayer va écrire à l'adresse qu'il connait, la même que dans tbB[0]… Normal donc de lire la même chose depuis tbB[0] que depuis tbA[0]

D'où l'utilité de slice pour obtenir une copie : un tableau affichant les mêmes valeurs, mais stockées selon des références différentes… :)

Vérifions :

var tbA:Array=new Array(15,30,50,20);
var tbB:Array=tbA.slice();
trace("tbA : "+tbA+"\ntbB : "+tbB);
//--> tbA : 15,30,50,20
//--> tbB : 15,30,50,20
tbA[0]=700;
trace("tbA : "+tbA+"\ntbB : "+tbB);
//--> tbA : 700,30,50,20
//--> tbB : 15,30,50,20



Attention dans les fonctions

Donc, les tableaux stockent les éléments par référence.
Pour illustrer à quel point ce n'est pas un détail, je vous propose l'exercice suivant : écrire une fonction qui attend un tableau (d'int) et renvoie la valeur la plus grande - sans modifier le tableau en question.

On l'appellerait comme suit :

var tbA:Array=new Array(15,30,50,20);
trace("tbA avant : "+tbA);
trace(donneMax(tbA));
trace("tbA après : "+tbA);

Comme on est en plein dans le chapitre, vous êtes attentif à cette histoire de références et vous n'écrivez pas :

function donneMax(a:Array):int {
	a.sort(Array.DESCENDING);
	return a[0];
}

Sans quoi, voilà ce qui se serait passé :

tbA avant : 15,30,50,20
50
tbA après : 50,30,20,15

Vous avez pensé à faire une copie du tableau passé en paramètre

function donneMax(a:Array):int {
	// copie de travail :))
	var tbCopie:Array=a.slice();
	tbCopie.sort(Array.DESCENDING);
	return tbCopie[0];
}




Conclusion

Voilà, pour ce qui est du primordial de l'important de l'incontournable de ce qu'il est bon de savoir quant aux tableaux, vous êtes au point. J'ai tout dit (ou presque). Je me suis appliquée à ne pas utiliser les mêmes exemples que ceux de la doc, quand c'était possible, pour que vous ayez à disposition différentes illustrations du même point. Je n'ai pas tout à fait tout dit en ce qui concerne indexOf et lastIndexOf, qui admettent un paramètre supplémentaire, et je n'ai pas précisé que la propriété length est en lecture/écriture… mais il faut bien que vous ayez le plaisir de découvrir des choses par vous même ;)
Qui a dit mauvaise foi !?
D'accord, c'était surtout pour ne pas alourdir l'exposé suffisamment conséquent à mon goût. Et puis j'aime pas les bruits de ronflement, ça perturbe ;)

En conséquence, et puisque vous avez survécu jusqu'ici, je vous invite, après une pause réparatrice, à faire connaissance avec 5 autres méthodes - espéciales AS3 - qui permettent de parcourir un tableau. Parcourir avec fonctions de rappel

Par ailleurs, uniquement pour FlashPlayer 10, nous disposons maintenant d'une classe Vector. Un vecteur est un tableau dont tous les éléments sont de même type. Les performances de cette classe sont peut-être meilleures que celles de Array, personne n'est d'accord et moi je ne me mouille pas ;)
Vous trouverez un tutoriel sur le sujet, ici. Rendez vous directement à la conclusion pour trouver un lien vers des tests de performance.



Liens utiles