Javascript 2d array indexOf

У меня есть такой массив 2d:

var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];

Каждый индекс хранит внутренний массив, содержащий координаты некоторого элемента.

Как я могу использовать Array.indexOf(), чтобы проверить, содержится ли вновь созданный набор координат в arr? Я хочу нажать arr, если только координата НЕ является дубликатом.

Вот моя попытка, которая не сработала:

if (arr.indexOf([x, y]) == -1) {
    arr.push([x, y]);
}

Похоже, что indexOf() не работает для 2d-массивов...

Ответ 1

Вы не можете использовать indexOf для создания сложных массивов (если вы не сериализуете его, делая все каждую координату в строки), вам нужно будет использовать цикл for (или while) для поиска этой координаты в этом массиве при условии, что вы знаете формат массив (в данном случае это 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]);
}

Эта реализация завершает и захватывает каждое значение. Если вы заботитесь о производительности, вы можете выполнять более сложные вещи, такие как сортировка исходного массива по первому индексу, а затем использование двоичного поиска по первому индексу.

Другим способом является ведение первой координаты каждого элемента в массиве в объекте (например, хэш-таблица) и ведение второго значения в каждом из этих кодов для сокращения времени поиска; подробнее здесь http://en.wikipedia.org/wiki/Bucket_sort.

В противном случае это, вероятно, достаточно хорошо для того, что вам нужно.

Ответ 2

Рабочая скрипка js

for(var k = 0; k < arr.length; k++){
    if(arr[k][0] == x && arr[k][1] == y){
        found = true;
    }
}

Значительно больше хакерский путь, чем простой индекс, но он работает

Ответ 3

Поскольку это двумерный массив, вам понадобится цикл вложенных циклов.

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;
}

Ответ 4

В предыдущем ответе говорилось:

Вы не можете использовать indexOf для создания сложных массивов (если вы не сериализуете его, делая все каждую координату в строки)...

Вот как вы это сделаете. Если у вас очень большой набор данных, я бы рекомендовал против этого метода, поскольку он полагается на дубликат вашего 2D-массива. Но для разумных наборов это просто.

Использовать согласованный метод для выравнивания элементов массива, например:

// Flatten array into a string, separating elements with a "unique" separator.
function stringle( arr ) {
  return arr.join(' |-| ');
}

Это избыток для вашего примера, где субмассивы содержат целые числа, но он учитывает более сложные типы данных. (Если бы мы использовали запятую, то по умолчанию она была бы неразличимой из строкового элемента, содержащего запятую, например.)

Затем целевой массив может быть сплющен в массив строк:

// Transmogrify arr into a String[], usable with indexOf()
var arrSearch = arr.map(function(row) { return stringle(row); });

Затем вы можете использовать Array.indexOf() (или другие методы массива), чтобы проверить наличие или расположение совпадений.

if (arrSearch.indexOf( stringle(newArray) ) === -1) ...

Этот фрагмент содержит демонстрацию этого файла с несколькими типами данных.

// 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>

Ответ 5

вы можете использовать этот метод,

function isArrayItemExists(array , item) {
    for ( var i = 0; i < array.length; i++ ) {
        if(JSON.stringify(array[i]) == JSON.stringify(item)){
            return true;
        }
            }
            return false;
}