javascript ne sait pas comparer des variables aryay ou des objets ?
ou encoreCode:
1
2
3 var foo=[0,2] var bar=[0,2] alert(foo==bar)
Code:
1
2
3 var foo={} var bar={} alert(foo==bar)
Version imprimable
javascript ne sait pas comparer des variables aryay ou des objets ?
ou encoreCode:
1
2
3 var foo=[0,2] var bar=[0,2] alert(foo==bar)
Code:
1
2
3 var foo={} var bar={} alert(foo==bar)
Non comme en java (et d'autres surement) tes variables foo et bar ont pour la valeur des références vers deux objets/tableaux différents.
Pour faire ce que tu veux faire tu dois implémenter une méthode equals qui comparerait non les références, mais les valeurs contenues dans la structure de donnée.
Cette méthode equals pouvant être récursive si ton objet/tableau contient d'autres objets/tableaux, et aussi gérer le cas où tu te trouverais dans une référence cyclique.
ben non, comparaison par référence...
[damned: I am grilled;]
Code:
1
2
3 for(i in foo){ if(bar[i]!=foo[i])alert("pas pareil") }
Pas vraiment :nono:Citation:
Envoyé par javatwister
[0, 1] serait sinon égal à [2, 1, 0] :whistle:
mais non 8O
(ce me semble; même si j'ai pas affiné)
sachant qu'on traite des tableaux avec la même organisation; à la moindre différence, tu peux demander un break;
??
foo[0] != bar[0]
([0,1])[0] != ([2,1,0])[0]
(0 != 2) -> BREAK
dans ce cas, ça fonctionne
par contre bien vu, dans le cas d'un objet (non array) si l'un des deux contient plus d'éléments que l'autre, la méthode de javatwister ne fonctionnera pas si le plus petit est comparé au plus grand.
pour les array, ça fonctionnera dans tous les cas, car l'un des "i" sera "length".
ben après on peut tester sur les arrays triés ou pas selon que l'on veuille une egalité des indexes et des contenus ou juste du contenu ...
Willpower: j'avoue
SpaceFrog: j'avoue
:mrgreen:
Arf, oui, j'ai été un peu enthousiaste... :aie:Citation:
Envoyé par Willpower
Mais on aura bien
:PCode:[0, 1] == [0, 1, 2]
Ou alors, il faut exécuter deux fois le code : foo ?== bar puis bar ?== foo.
en testant length à la base, pas problème, je pense;
relis mon message. ;-)
dans le cas d'array, un "for(i in obj)" assignera succesivement au "i" tous les indices du tableau ainsi que la valeur "length"(il me semble) donc la longueur des array sera comparé et ça empechera ce genre d'erreur.
EDIT: oups, je retire ce que j'ai dis au sujet du length, apparement je me suis fourvoyé. il faut bien tester length en plus. :oops:
par contre pour les objets (non array), il faudra utiliser une solution comme proposée ici :
http://stackoverflow.com/questions/1...-in-javascript
bien que je ne comprends pas pourquoi il compare les "function" sous forme de string au lieu de le gérer comme le reste avec une comparaison normale. (sauf s'il veut inclure dans sa comparaison des fonctions similaires mais non-égales en terme de signature/prototype).
et je ne comprend surtout pas pq il crée 3 boucles au lieu de 2 (la première pouvant être include dans la seconde.)
pour les arrays on dirait que l'on peut utiliser .toString()
pour les json nonCode:
1
2
3 var foo=[0,1] var bar=[0,1] alert(foo.toString()==bar.toString())
oui Spaf, puisque là, tu retrouves une comparaison par valeur (String...)
voici le code corrigé du lien que j'ai donnée plus haut. (avec optimisation pour les arrays, sans plantage pour les objets dom, etc..)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 Object.prototype.equals = function(x){ var p; if( typeof(x) != 'object' ) return false; if( (x.length || this.length) && (x.length !== this.length) ) return false; for(p in this) { if( typeof(x[p]) == 'undefined' ) return false; switch( typeof(this[p]) ){ case 'function': if( typeof(x[p]) == 'undefined' || this[p].toString() != x[p].toString() ) return false; break; case 'object': // array or object(no dom) with recurse if( !this[p].nodeType ){ if( !this[p].equals(x[p]) ) return false; break; } default: if (this[p] != x[p]) return false; } } if( typeof(x.length) == 'undefined' ) for(p in x) if( typeof (this[p]) == 'undefined' ) return false; return true; };
Je suis très surpris que tu ouvres un topic pour une chose aussi simple que la comparaison d'objets en JS qui ne se fait que sur des références. Alors que tu fais pleins de choses en JS à coté.
Attention au toString(); ça ne fait que te retourner le tableau en string et du coup tu te retrouves avec une comparaison de types primitifs
Et attention justement à ne pas tester un tableau d'objet de cette manière, car sinon tu peux te retrouver avec des résultats de ce genre :
Car de chaque coté on a : "[object Object],[object Object]" comme valeur.Code:
1
2
3 [{},{}].toString()==[{titi:"tata"},{tuto:1}].toString(); => true
Et si je me rappelle bien je crois que tu as déjà écris une méthode de copie récursive, tu pourrais donc t'en servir pour tester l'égalité de 2 objets :D
C'est juste pour relancer un troll... :aie:
Au départ je suis tombé sur un teste d'égalité alert([]==[]) en bidouillant une sorte de empty() pour javascript.
Ensuite ma curiosité m'a poussé à vouloir comparer des arrays et des jsons, sans trier ni boucler, ni importer une lib.
Forcément le toString() masque les types, mais bon js et typage ...
Bon encore une fois je tentais de réinventer le fil à couper l'eau tiède ...
T'as raison ma poule! faut pas se laisser aller :ccool:Citation:
Envoyé par SpaceFrog