OVH Cloud OVH Cloud

boucle dans un tableau indicé de façon non consécutive

26 réponses
Avatar
jero
Bonjour

je suis en train de me prendre les pieds dans le tapis ...

j'ai r=E9cup=E9r=E9 des donn=E9es dans une base de donn=E9es via
XMLHttpRequest jusque l=E0 tout va bien.
j'ai stock=E9 ces donn=E9es dans une variable globale de mon javascript :

var window.mesDonnees =3D new Array();

Afin de stock=E9 chaque colonne de chaque ligne r=E9cup=E9r=E9e dans ma
base j'ai imbriqu=E9 un tableau dans mon tableau windows.mesDonnes que
j'ai indic=E9 avec l'identifiant num=E9rique de chaque =E9l=E9ment
r=E9cup=E9r=E9 :

var window.mesDonnees[identifiantNum=E9rique] =3D new Array();

de sorte de pouvoir y stocker les valeur r=E9cup=E9r=E9es dans chaque
colonne

var window.mesDonnees[identifiantNum=E9rique][0] =3D valeurColonne_0
var window.mesDonnees[identifiantNum=E9rique][1] =3D valeurColonne_1
etc...

je ne trouve pas de methode pour faire une boucle dans mon tableau au
niveau ou il est indic=E9 par les identifiants num=E9riques, dans la
mesure o=F9 ils ne sont pas n=E9cessairement cons=E9cutifs !

de sorte que le classique

for ( var i =3D 0 ; i < window.mesDonnees.length ; i++) {
window.mesDonnees[i] faitQuelqueChose;
}

n'est pas op=E9rationnel ...

connaissez vous une m=E9thode qui pourrai fonctionner ? un genre
d'=E9quivalent =E0 la boucle 'for each' du PHP ?

D'avance grand merci !
J=E9r=F4me

10 réponses

1 2 3
Avatar
Laurent vilday
Laurent vilday wrote:
Il semblerait donc que la notation [] soit à *recommander* par rapport
à la notation new Array(), au moins pour ces 3 navigateurs en
environnement windows (pas le courage de tester ni en slackware ni sur
d'autres navigateurs, j'ai assez perdu mon temps avec ça), puisque :
- la notation courte [] va un tantinet plus vite,
- permet une écriture plus concise,
- permet de préremplir les tableaux de façon simplifiée,
- permet même la création de tableaux multidimensionnels ce que ne
permet pas new Array().


En effet ça semble assez séduisant d'un point de vue syntaxe
Par contre quid du support ? (je pense en particulier à IE 5 et Safari ?)


De mémoire, la notation courte (literal array) a été introduite en
Javascript 1.2. Je n'ai malheureusement aucun moyen de vérifier mais à
priori IE5 ça devrait pas lui poser de problème, quand à safari, je ne
vois que ASM pour pouvoir nous dire si oui ou non c'est utilisable.
J'aurai tendance à dire que oui mais sans aucune certitude
malheureusement :(

--
laurent


Avatar
ASM
Laurent vilday wrote:
Il semblerait donc que la notation [] soit à *recommander* par
rapport à la notation new Array(), au moins pour ces 3 navigateurs en
environnement windows (pas le courage de tester ni en slackware ni
sur d'autres navigateurs, j'ai assez perdu mon temps avec ça), puisque :
- la notation courte [] va un tantinet plus vite,
- permet une écriture plus concise,
- permet de préremplir les tableaux de façon simplifiée,
- permet même la création de tableaux multidimensionnels ce que ne
permet pas new Array().


En effet ça semble assez séduisant d'un point de vue syntaxe
Par contre quid du support ? (je pense en particulier à IE 5 et Safari ?)


De mémoire, la notation courte (literal array) a été introduite en
Javascript 1.2. Je n'ai malheureusement aucun moyen de vérifier mais à
priori IE5 ça devrait pas lui poser de problème, quand à safari, je ne
vois que ASM pour pouvoir nous dire si oui ou non c'est utilisable.
J'aurai tendance à dire que oui mais sans aucune certitude
malheureusement :(


Bon, à mon idée, cette notation courte n'est pas nouvelle nouvelle,
Même sous NC4 c'est OK. C'est dire !

<script type="text/javascript">
var I = [1,'truc','bidule'];
alert(I); // 1,truc,bidule
alert(I[2]); // bidule
</script>

alors si Safari n'y arrive pas ...
y a pu qu'à tirer l'échelle !

Mais que les foules attentives se rassurent :
Safari passe le test ci-dessus

Quant à dire que Array() ne permet pas les tableaux multidimensionnels
...
personne ne m'avait prévenu !
Ce qui est curieux c'est que Array() ne semble pas être au courant de
cette nouveauté.

--
Stephane Moriaux et son [moins] vieux Mac



Avatar
Laurent vilday
Quant à dire que Array() ne permet pas les tableaux multidimensionnels
...
personne ne m'avait prévenu !
Ce qui est curieux c'est que Array() ne semble pas être au courant de
cette nouveauté.


Lol, j'étais tellement énervé par tant d'instance de la part de YD sur
des remarques totallement erronnées, que j'en ai oublié des mots :)

Quand je disais :
- permet même la création de tableaux multidimensionnels ce que ne
permet pas new Array().

En fait je pensais :
- permet même /de façon rapide et concise/ la création de tableaux
multidimensionnels ce que ne permet pas /aussi facilement/ new Array().

Ceci pour dire que

var tbl = [[[1,2,3], [2,3,4]], {foo:'bar',bar:'foo'}, [10], [20]];

est bien plus rapide a écrire, et à lire mais ça c'est personnel je
pense, que :

var tbl = new Array();
tbl[0] = new Array();
tbl[0][0] = new Array(1, 2, 3);
tbl[0][1] = new Array(2, 3, 4);
tbl[1] = new Object();
tbl[1].foo = 'bar';
tbl[1].bar = 'foo';
tbl[2] = new Array();
tbl[2][0] = 10;
tbl[3] = new Array()
tbl[3][0] = 20;

Merci Stéphane pour ce rappel qui méritait effectivement une précision.

self note : après s'être relu une dizaine de fois, recommencer et se
relire encore :D

--
laurent

Avatar
Pierre Goiffon
ASM wrote:
- la notation courte [] va un tantinet plus vite,
- permet une écriture plus concise,
- permet de préremplir les tableaux de façon simplifiée,
- permet même la création de tableaux multidimensionnels ce que ne
permet pas new Array().


En effet ça semble assez séduisant d'un point de vue syntaxe
Par contre quid du support ? (je pense en particulier à IE 5 et
Safari ?)


De mémoire, la notation courte (literal array) a été introduite en
Javascript 1.2. Je n'ai malheureusement aucun moyen de vérifier mais à
priori IE5 ça devrait pas lui poser de problème, quand à safari, je ne
vois que ASM pour pouvoir nous dire si oui ou non c'est utilisable.


Même sous NC4 c'est OK. C'est dire !
(...)

Safari passe le test ci-dessus


Merci à vous 2 pour toutes ces explications !




Avatar
YD
4) Ce que tu appelles "notation courte" versus "notations d'un âge
antidéluvien" (quel argument !)
[...]
Tu peux donc trouver cela très pratique mais ce n'est qu'une facilité
d'écriture et n'est pas particulièrement à recommander.



Je dis bien *pas particulièrement à recommander*.

Et bien, il suffit de vérifier pour se persuader du contraire :


J'ai refait tes tests tels que puis en modifiant les créations
d'Array (en les initialisant avec quelques valeurs pour voir).
Même chose dans les deux cas : résultats comparables dans les
mêmes proportions pour IE6 et Opera 9 mais avec Fx 2.0b2, les
résultats sont inverses (plus longs avec l'écriture condensée)

new Array() 4082 (de 4 à 5 fois plus long que IE et Op)
[] 4711 (temps moyens sur 5 essais)

J'ai rajouté une troisième écriture : Array() (sans new). C'est
un peu plus long à traiter que new Array() pour IE et Fx, mais
très légèrement plus rapide avec Opera.

Les fonctions comme je les ai modifiées sont à la fin du post.
----
Puisque les Array ont l'air d'intéresser...

a) Une bizarrerie remarquée (bug ?). Quand on crée un Array non
densément peuplé -- ce qui se fait très bien avec la notation courte
mais pas avec le constructeur -- comme par exemple :

var t = ['A',,,'B'];
for (var i in t) document.write(i + ' -> ' + t[i] + '<br>');

On obtient le résultat escompté avec IE et Op :
0 -> A
3 -> B

mais Firefox 2.0b2 répond
0 -> A
1 -> undefined
2 -> undefined
3 -> B

À tester également [,,,,] qui retourne un résultat différent dans ces
3 navigateurs !

b) Il est possible d'écrire presque la même chose avec les notations
constructeur et condensées sauf pour
- un Array non densément peuplé (impossible d'écrire new Array(1,,,3))
- un Array à un seul élément comme [5], car new Array(5) crée un tableau
dont la propriété length est 5 mais qui ne contient aucun élément défini :
for ... in ... ne retourne rien.

Par exemple :
var tbl = [[[1,2,3], [2,3,4]], {foo:'bar',bar:'foo'}];

peut s'écrire :

var tbl = new Array(
new Array(
new Array(1,2,3),
new Array(2,3,4)),
new function()
{this.foo='bar'; this.bar='foo';});

C'est certes moins élégant mais pas moins possible et tout aussi
lisible.

----
Les fonctions de test modifiées

function b1()
{
bench.init('new Array()');
var X, Y;
for ( var i = 0; i < 50000; i++ )
{
X = new Array("a","b","c",123,456,7890);
Y=new Array(new Array(), new Array());
}
MSG += bench.T + ' : ' + bench.fin() + '<br>';
setTimeout(b2, 50);
}

function b2()
{
bench.init('Array()');
var X, Y;
for ( var i = 0; i < 50000; i++ )
{
X = Array("a","b","c",123,456,7890);
Y= Array( Array(), Array());
}
MSG += bench.T + ' : ' + bench.fin() + '<br>';
setTimeout(b3, 50);
}

function b3()
{
bench.init('[]');
var X, Y;
for ( var i = 0; i < 50000; i++ )
{
X = ["a","b","c",123,456,7890];
Y=[[],[]];
}
MSG += bench.T + ' : ' + bench.fin() + '<br>';
document.getElementById('results').innerHTML = MSG;
}

--
Y.D.


Avatar
YD
J'interviens encore une fois sur le sujet...

Je ne vais pas répondre dans le fil, ça serait indigeste, mais reprendre
quelques points et développer.


Mouais évidemment, ça va aider à comprendre c'est certain. D'un autre
côté, ça va te permettre de me préter des paroles qui ne sont pas les
miennes, belle technique.


Mais tu es infect ! Quels propos je t'ai indûment prêtés ? le 'mieux' ?
Je n'avais pas écrit "mieux".

1) L'OP devait-il utiliser un Array ?


Non !
[...] Toute la problématique est résumé avec ces 3 mots :
"pas nécessairement consécutifs"


Un Array n'a pas forcément une valeur pour chaque indice, par définition.
C'est bizarre mais c'est propre au JS.

Par ailleurs on ne sait pas quelles propriétés spécifiques aux Arrays
sont utilisées. S'il n'y en a aucune, il est alors possible d'utiliser
des Objects mais pourquoi pas un Array qui permettra de connaître très
vite le plus grand identifiant numérique utilisé (mesDonnees.length-1).


Non, ce n'est pas consécutifs, d'après ce qu'il dit il a potentiellement
ceci :

mesDonnees[0] = [];
mesDonnees[1] = [];
mesDonnees[31] = [];
mesDonnees[20] = [];
mesDonnees[8] = [];

alert(mesDonnees.length - 1);
// 31

31 ?!?! Ce n'est pas vrai, tout simplement.


Eh bien c'est le plus grand identifiant utilisé. Qu'est-ce qui n'est pas
vrai mon garçon ?

Je remets l'url qui explique bien mieux que moi pourquoi il ne faut
*pas* utiliser un Array() dans ce cas précis puisque tu insistes dans
cette direction qui est fausse, et même pire que fausse, c'est la
direction à ne *pas* prendre :
http://www.andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/


J'y avais jeté un coup d'oeil et sur les commentaires aussi. Le moins
qu'on puisse dire c'est que l'article ne fait pas l'unanimité.

Ce qu'il a besoin n'est pas un tableau au sens Array() du terme
javascript mais bien un Object().


Je l'ai déjà écrit, je ne sais pas s'il utilise d'autres propriétés des Array.

2) La question de l'OP était : existe-t-il un moyen de parcourir un Array
qui n'est pas 'dense' (qui ne possède pas une valeur pour chaque indice
inférieur à sa propriété length) ?

La réponse est oui, for(p in o) qui énumérera en p les propriétés
énumérables définies de l'objet o.


Oui, ai-je proposé qqchose de différents ?


Je ne t'ai pas contredit sur ce point. Ce que tu n'as pas dit, et ce
pourquoi je suis intervenu, est que cela marche bien pour un Array et
répond exactement à la question clairement énoncée de l'OP : comment
énumérer les indices non consécutifs d'un Array.

Et comme tu le dis - l'objet o - alors pourquoi aller utiliser un
Array() quand on parle d'Object() ? On retombe sur le problème
d'utiliser un type incompatible avec le besoin.


Quel type incompatible ? Un Array est un objet JS avec des commodités
particulières.

var x = new Boolean();
x[0] = 'foo'; x[10] = 'bar'; x[20] = 'foobar';
for ( var i in x ) alert(i);
Ca donne : 0 puis 10 puis 20

Est-ce une raison pour autant d'aller utiliser un Boolean() ? non !


Sauf si ça me chante car c'est licite et syntaxiquement correct en JS.

Ceci n'est pas propre aux Arrays mais
à tous les objets JS. Ça présente l'avantage pour les Arrays de ne donner
que les "indices" pour lesquels une valeur est définie. Il donnera
également
les autres propriétés qu'on aura pu ajouter à l'objet Array... Se servir
dans les Arrays des méthodes et opérateurs définis pour les Objects c'est
prévu. Et ce n'est pas un miracle, c'est de la programmation orientée
objet -- enfin, tu dois le savoir.


Ah, et depuis quand javascript est orienté objet ?


"ECMAScript is an object-oriented programming language for performing
computations and manipulating computational objects within a host environment."
(ECMA 262 p. 1)

C'est un langage
prototypé, pas du tout objet dans le sens OOP qu'on peut trouver en php
par exemple. Faire l'amalgamme n'est pas aider le lecteur.


Pour le coup, je ne suis pas sûr que c'est moi qui dise des inepties...

3) [...]
Tout ce que tu as dit là n'ajoute rien au débat. C'est attaque personnelle


sur attaque personnelle. Aucun intérêt.


4) Ce que tu appelles "notation courte" versus "notations d'un âge
antidéluvien" (quel argument !)


Lol, comme si c'était le seul "argument" que j'avais énoncé. Et quand tu
me demandes les différences et que je réponds "presque aucune". Est-ce
que tu comprends autre chose ? Encore une fois, tant pis.

Pour ces notations abrégées de l'initialisation d'un Array ou Object,
la norme ECMA262 emploie l'expression Array Initialiser :


Oui, chapitre 11.1.4 et appendice A.3, où la norme parle d'expression.

<snip>

Dans un cas on fait appel explicitement au constructeur, dans l'autre
c'est implicite.


Et ? Si je te suis bien et en appliquant ton raisonnement (explicite vs
implicite) à tous les types existants en javascript, tu prétends que

var x = new String('foo');

serait à conseiller au dépend de

var x = 'foo';


Non, Môssieu. Dans x='foo', 'foo' est une valeur primitive du langage et x
une référence vers cette valeur. Alors que dans x = new String('foo'),
x est un objet !

Array par contre ne fait pas partie des types primitifs du langage.

Ceci dit, si tu avais essayé de comprendre, je disais que ces écritures sont
équivalentes. En bref c'est plus un choix esthétique, des habitudes (un
programmeur Java va certainement préférer utiliser les constructeurs alors
qu'un programmeur PERL les formes condensées) qui vont dicter la
préférence la plupart du temps.

Les deux existent, alors pourquoi prétendre que pour le type tableau
(Array) la notation courte est à proscrire. J'ai juste énoncé le fait
que ça existait, pas que c'était préférable, simplement que ça existait.


Je n'avais pas compris le sens de antédiluvien alors (pardon tu as écrit
antidéluvien, je ne voulais pas déformer tes propos).

Tu peux donc trouver cela très pratique mais ce n'est qu'une facilité
d'écriture et n'est pas particulièrement à recommander. On se sert de
l'un ou l'autre selon ses besoins et préférences -- et ce n'est pas
parce qu'un script est abscons qu'il est forcément 'mieux'.


Encore une fois, tu m'as lu de travers et tu m'attribues des paroles qui
ne sont *pas*, n'ont jamais et ne seront jamais les miennes.

J'ai jamais dit 'mieux' ni recommandé de l'utiliser, relis moi *mieux*,
j'ai dit :

<cite>
new Array() est transformable à volonté par []
</cite>

Ce qui sous entend bien qu'on peut se servir de l'un ou de l'autre selon
ses besoins et préférences. Et ce n'est pas être abscons que d'indiquer
que ça existe, d'autant plus que la norme, toujours chapitre 11.1.4,
indique bien que la notation est valide. D'autant que tu prétends que ce
n'est pas à recommander, alors je vais te retourner la question. Tu sors
ça d'où que c'est pas recommandé ?


Fais la nuance entre
"pas à recommander" (ce que tu me fais dire)
et
"pas particulièrement à recommander" (ce que j'ai écrit).

[...]
Pour finir sur le sujet, saches que non, je suis loin d'être persuadé de
détenir une quelconque vérité sur le bon usage de javascript, mais je
suis absolument convaincu du fait que tu ne la détiens pas.


Bon, on est d'accord sur ces deux points.

Considère ça
comme une attaque ad hominem si ça te chante, et profites en pour relire
la réponse que tu avais faite à mon message, réponse où tu avais
commencé les hostilités.


Exact, car je trouve que tu aurais pu répondre plus simplement : commencer (et
non finir) par la solution du for...in, ajouter ensuite d'autres
considérations sur l'utilité de l'Array, sur les questions de style, etc. et
préciser que le script n'était pas forcément à réécrire car les [] sont un cas
particulier de {} et que ce qui marche pour les {} marche aussi pour les [] et
que cela était syntaxiquement correct, même si tu avais des réserves à apporter
sur les Arrays non denses).

Pour moi, encore quelques remarques ineptes sur les Arrays (ton test, autre
message) et fin du fil.


--
Y.D.


Avatar
Laurent vilday
J'interviens encore une fois sur le sujet...


T'aurais mieux fait de t'abstenir, tu continues a raconter n'importe
quoi, à mélanger mes dires et à être d'une mauvaise foi incroyable. A
l'avenir oublies moi et contentes toi de donner des solutions *valides*
dans les temps au lieu de venir avec tes gros sabots raconter des
inepties énormes en prétendant détenir la solution alors que la solution
correcte a déjà été fournie et appréciée à sa juste valeur par l'OP !

Adieu.

--
laurent

Avatar
ASM
J'interviens encore une fois sur le sujet...


T'aurais mieux fait de t'abstenir,
[...]

Adieu.


Y a pas, vous êtes trop bonnards :-)
On se croirait sur comp.lang.javascript
C'est très distrayant bien que de temps en temps instructif.
J'espère vous revoir très bientôt.

--
Stephane Moriaux et son [moins] vieux Mac


Avatar
ASM
T'aurais mieux fait de


Je suppose que tu as lu :


ATH
--
Stephane Moriaux et son [moins] vieux Mac

Avatar
BertrandB

a) Une bizarrerie remarquée (bug ?). Quand on crée un Array non
densément peuplé -- ce qui se fait très bien avec la notation cou rte
mais pas avec le constructeur -- comme par exemple :

var t = ['A',,,'B'];
for (var i in t) document.write(i + ' -> ' + t[i] + '<br>');

On obtient le résultat escompté avec IE et Op :
0 -> A
3 -> B

mais Firefox 2.0b2 répond
0 -> A
1 -> undefined
2 -> undefined
3 -> B


Sémantiquement firefox est dans le vrai ["A",,,"B"]moi je lis un tablea u
de 4 éléments dony le 2ème et le 3ème n'ont pas été définis .

Un tableau creux je l'écrirais !
t=new Array();
t[0]="A";
t[3]="B";
for (var i in t) print(i + ' -> ' + t[i] + '<br>');
Et là firefox répond
0 -> A<br>
3 -> B<br>
Mais dans quel cas je préférerais une notation de type dictionnaire.
t={0:'A',3:'B'};
for (var i in t) print(i + ' -> ' + t[i] + '<br>');
Et firefox répond
0 -> A<br>
3 -> B<br>

1 2 3