Javascript indexOf pour un tableau de tableaux ne trouvant pas de tableau

J’ai un tableau avec des tableaux nesteds qui ressemble à ceci:

var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; 

Quand j’essaie de trouver si le tableau tw contient un tableau passé, j’obtiens toujours un résultat de -1.

Par exemple:

 var test = $.inArray([3, 0], tw); var test2 = tw.indexOf([3, 0]); 

les deux retournent -1, même si le premier object du tableau est [3,0] Comment savoir si un tableau spécifique de tableaux est contenu dans mon tableau?

Oh, et je ne l’ai testé que sur IE9 jusqu’à présent.

C’est parce que vous recherchez un autre object. indexOf() utilise des comparaisons d’égalité ssortingctes (comme l’opérateur === ) et [3, 0] === [3, 0] renvoie false.

Vous aurez besoin de rechercher manuellement. Voici un exemple d’utilisation d’une fonction indexOf() plus générique qui utilise une fonction de indexOf() personnalisée (avec une amélioration suggérée par @ ajax333221 dans les commentaires):

 // Shallow array comparer function arraysIdentical(arr1, arr2) { var i = arr1.length; if (i !== arr2.length) { return false; } while (i--) { if (arr1[i] !== arr2[i]) { return false; } } return true; } function indexOf(arr, val, comparer) { for (var i = 0, len = arr.length; i < len; ++i) { if ( i in arr && comparer(arr[i], val) ) { return i; } } return -1; } var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; alert( indexOf(tw, [3, 0], arraysIdentical) ); // Alerts 0 

Les tableaux sont des objects . [3, 0] n’est pas égal à [3, 0] car il s’agit d’objects différents. C’est pourquoi votre inArray échoue.

Parce que vous comparez deux instances différentes de array. La comparaison d’objects ne renvoie true que si elles sont la même instance, peu importe si elles contiennent les mêmes données.

Dans votre cas, vous pouvez utiliser cette approche:

 var tw = [[3, 0], [11, 0], [3, 14], [11, 14]]; if (~tw.join(";").split(";").indexOf(Ssortingng([3, 0]))) { // ... } 

Ou quelque chose de plus orthodoxe comme:

 if (tw.filter(function(v) { return Ssortingng(v) === Ssortingng([3, 10]) })[0]) { // ... } 

Où la condition peut être ajustée dépend du contenu des tableaux.

Pour une recherche nestede infinie:

 function indexOfArr(arr1, fnd1) { var i, len1; //compare every element on the array for (i = 0, len1 = arr1.length; i < len1; i++) { //index missing, leave to prevent false-positives with 'undefined' if (!(i in arr1)) { continue; } //if they are exactly equal, return the index if (elementComparer(arr1[i], fnd1)) { return i; } } //no match found, return false return -1; } function elementComparer(fnd1, fnd2) { var i, len1, len2, type1, type2, iin1, iin2; //store the types of fnd1 and fnd2 type1 = typeof fnd1; type2 = typeof fnd2; //unwanted results with '(NaN!==NaN)===true' so we exclude them if (!((type1 == "number" && type2 == "number") && (fnd1 + "" == "NaN" && fnd2 + "" == "NaN"))) { //unwanted results with '(typeof null==="object")===true' so we exclude them if (type1 == "object" && fnd1 + "" != "null") { len1 = fnd1.length; //unwanted results with '(typeof null==="object")===true' so we exclude them if (type2 == "object" && fnd2 + "" != "null") { len2 = fnd2.length; //if they aren't the same length, return false if (len1 !== len2) { return false; } //compare every element on the array for (i = 0; i < len1; i++) { iin1 = i in fnd1; iin2 = i in fnd2; //if either index is missing... if (!(iin1 && iin2)) { //they both are missing, leave to prevent false-positives with 'undefined' if (iin1 == iin2) { continue; } //NOT the same, return false return false; } //if they are NOT the same, return false if (!elementComparer(fnd1[i], fnd2[i])) { return false; } } } else { //NOT the same, return false return false; } } else { //if they are NOT the same, return false if (fnd1 !== fnd2) { return false; } } } //if it successfully avoided all 'return false', then they are equal return true; } 

Remarques:

  • prend en charge des tableaux nesteds infinis
  • gère correctement les tableaux épars
  • utilise des contrôles de type

jsFiddle demo

Ceci est dû au fait que $.inArray et indexOf utilisent tous deux une comparaison superficielle utilisant === .

Puisque le tableau que vous passez est à indexOf n’est pas exactement le même en mémoire que celui de votre tableau 2D, === renvoie false. Vous devrez faire une comparaison approfondie pour trouver le tableau correctement. D’un coup d’œil rapide à la documentation jQuery, ceci n’est pas disponible ici.

Pourquoi ne pas garder les choses simples?

 function indexOfCustom (parentArray, searchElement) { for ( var i = 0; i < parentArray.length; i++ ) { if ( parentArray[i][0] == searchElement[0] && parentArray[i][1] == searchElement[1] ) { return i; } } return -1; }