J'ai un tableau 2D comme ça:
var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
Chaque index stocke un tableau interne contenant les coordonnées d'un élément.
Comment utiliser Array.indexOf()
pour vérifier si le nouveau jeu de coordonnées généré est déjà contenu dans arr
? Je veux pousser dans arr
si seulement la coordonnée n'est pas un doublon.
Voici ma tentative qui n'a pas fonctionné:
if (arr.indexOf([x, y]) == -1) {
arr.Push([x, y]);
}
Il semble que indexOf()
ne fonctionne pas pour les tableaux 2D ...
Vous ne pouvez pas utiliser indexOf pour faire des tableaux compliqués (sauf si vous le sérialisez en transformant chaque coordonnée en chaîne), vous devrez utiliser une boucle for (ou while) pour rechercher cette coordonnée dans ce tableau en supposant connaître le format du tableau ( dans ce cas c'est 2d).
var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
var coor1 = [0, 9];
var coor2 = [1, 2];
function isItemInArray(array, item) {
for (var i = 0; i < array.length; i++) {
// This if statement depends on the format of your array
if (array[i][0] == item[0] && array[i][1] == item[1]) {
return true; // Found it
}
}
return false; // Not found
}
// Test coor1
console.log("Is it in there? [0, 9]", isItemInArray(arr, coor1)); // True
// Test coor2
console.log("Is it in there? [1, 2]", isItemInArray(arr, coor2)); // False
// Then
if (!isItemInArray(arr, [x, y])) {
arr.Push([x, y]);
}
Cette implémentation boucle et saisit chaque valeur. Si vous vous souciez des performances, vous pouvez faire des choses plus compliquées, comme trier le tableau d'origine par le premier index, puis utiliser la recherche binaire sur le premier index.
Une autre méthode consiste à classer la première coordonnée de chaque élément du tableau dans un objet (comme une table de hachage) et la deuxième valeur dans chacun de ces compartiments afin de réduire les temps de recherche; plus d'infos ici http://en.wikipedia.org/wiki/Bucket_sort .
Sinon, c'est probablement suffisant pour ce dont vous avez besoin.
for(var k = 0; k < arr.length; k++){
if(arr[k][0] == x && arr[k][1] == y){
found = true;
}
}
Beaucoup plus d'une manière hacky qu'un simple index de, mais cela fonctionne
Pas une réponse complète, juste une note de côté qui peut aider.
Utilisez Lodash
Cette méthode vous permettra d'obtenir la position d'une valeur dans un tableau à 2 dimensions
let a = [ [ 'bird' ], [ 'cat' ], [ 'dog' ], [ 'cow' ], [ 'bird' ] ];
let b = _.findIndex(a, function(el) { return el[0] == 'cow'; });
console.log(b);//answer is 3
Comme mentionné précédemment, vous avez besoin d'une boucle imbriquée pour parcourir le tableau.
Comme il s'agit d'un tableau à deux dimensions, vous aurez besoin d'une boucle for imbriquée.
var newArr = [1, 2],
counter;
for ( var i = 0; i < arr.length; i++ ) {
for ( var x = 0; x = arr[i].length; x++ ) {
if ( arr[i][x] === newArr[x] {
counter++
}
if (counter === 2) {
alert('new coord!')
}
}
//reset counter
counter = 0;
}
vous pouvez utiliser cette méthode,
function isArrayItemExists(array , item) {
for ( var i = 0; i < array.length; i++ ) {
if(JSON.stringify(array[i]) == JSON.stringify(item)){
return true;
}
}
return false;
}
Très simple sans indexOf ...
var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
const isDup = (x,y) => {
arr.find(it => JSON.stringify(it) == JSON.stringify([x,y])) == undefined ? arr.Push([x,y]) : null
}
console.log(isDup(2,3)) /* Does not add */
console.log(isDup(1,2)) /*Does add*/
console.log(arr) /*Confirmation*/
Une réponse précédente disait:
Vous ne pouvez pas utiliser indexOf pour faire des tableaux compliqués (à moins que vous ne le sérialisiez en transformant chaque coordonnée en chaîne) ...
Voici comment vous feriez cela. Si vous avez un ensemble de données extrêmement volumineux, je vous déconseille cette technique, car elle repose sur une copie de votre tableau 2D. Mais pour des ensembles raisonnables, c'est simple.
Utilisez une méthode cohérente pour aplatir des éléments de tableau, tels que:
// Flatten array into a string, separating elements with a "unique" separator.
function stringle( arr ) {
return arr.join(' |-| ');
}
Ceci est excessif pour votre exemple, où les sous-tableaux contiennent des entiers, mais cela représente des types de données plus complexes. (Si nous utilisions une virgule, la valeur par défaut serait indiscernable d'un élément de chaîne contenant une virgule, par exemple.)
Ensuite, le tableau cible peut être aplati en un tableau de chaînes:
// Transmogrify arr into a String[], usable with indexOf()
var arrSearch = arr.map(function(row) { return stringle(row); });
Ensuite, vous pouvez utiliser Array.indexOf()
(ou d’autres méthodes de tableau) pour vérifier la présence ou l’emplacement des correspondances.
if (arrSearch.indexOf( stringle(newArray) ) === -1) ...
Cet extrait de code en contient une démonstration, avec plusieurs types de données.
// Example starting array
var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
// Flatten array into a string, separating elements with a "unique" separator.
function stringle( arr ) {
return arr.join(' |-| ');
}
snippet.log("arr: "+JSON.stringify(arr));
// Transmogrify arr into a String[], usable with indexOf()
var arrSearch = arr.map(function(row) { return stringle(row); });
snippet.log("arrSearch: "+JSON.stringify(arrSearch));
var tests = [[0, 9],[1, 2],["pig","cow"],[0,9,"Unicorn"],["pig","cow"]];
for (var test in tests) {
var str = stringle(tests[test]);
if (arrSearch.indexOf(str) === -1) {
arr.Push(tests[test]);
arrSearch.Push(str);
snippet.log("Added "+JSON.stringify(tests[test]));
}
else {
snippet.log("Already had "+JSON.stringify(tests[test]));
}
}
snippet.log("Result: "+JSON.stringify(arr));
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>