Проверьте, существует ли массив в массиве массивов?

Я использую JavaScript и хочу проверить, существует ли массив в массиве массивов.

Вот мой код вместе с возвращаемыми значениями:

var myArr = [1,3];
var prizes = [[1,3],[1,4]];
prizes.indexOf(myArr);
-1

Почему?

То же самое в jQuery:

$.inArray(myArr, prizes);
-1

Почему это возвращает -1, когда элемент присутствует в массиве?

Ответ 1

Потому что [1,3] !== [1,3], поскольку объекты будут равны только, если они ссылаются на один и тот же объект. Вам необходимо написать собственную процедуру поиска:

function searchForArray(haystack, needle){
  var i, j, current;
  for(i = 0; i < haystack.length; ++i){
    if(needle.length === haystack[i].length){
      current = haystack[i];
      for(j = 0; j < needle.length && needle[j] === current[j]; ++j);
      if(j === needle.length)
        return i;
    }
  }
  return -1;
}

var arr = [[1,3],[1,2]];
var n   = [1,3];

console.log(searchForArray(arr,n)); // 0

Ссылки

  • Использование операторов равенства:

    Если оба операнда являются объектами, они сравниваются как объекты, и проверка равенства истинна, только если оба относятся к одному и тому же объекту.

Ответ 2

Вы можете использовать это var a = [ [1,2] , [3,4] ]; var b = [1,2]; a = JSON.stringify(a); b = JSON.stringify(b);

то вы можете сделать только indexOf(), чтобы проверить, присутствует ли он var c = a.indexOf(b); if(c != -1){ console.log('element present'); }

Ответ 3

Потому что оба эти метода используют ссылочное равенство при работе с объектами. Массив, который существует и тот, который вы ищете, может быть структурно идентичным, но они являются уникальными объектами, поэтому они не будут сравниваться как равные.

Это даст ожидаемый результат, даже если это не полезно на практике:

var myArr = [1,3];
var prizes = [myArr,[1,4]];
prizes.indexOf(myArr);

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

Ответ 4

Поскольку объекты javascript сравниваются по идентификатору, а не по значению. Поэтому, если они не ссылаются на один и тот же объект, они вернут false.

Вам нужно сравнить рекурсивно, чтобы это нормально работало.

Ответ 5

сначала определите функцию сравнения для массивов

// attach the .compare method to Array prototype to call it on any array
Array.prototype.compare = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].compare(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}

second просто найдите массив с

prizes.filter(function(a){ return a.compare(myArr)})

ПРИМЕЧАНИЕ. Проверьте совместимость браузера array.filter

Ответ 6

Предполагая, что вы имеете дело только с двумерным массивом (вы упоминаете "массив массивов", но ничего глубже этого), этот нерекурсивный код должен делать то, что вам нужно.

var compare_arrays = function (array_a, array_b) {
    var rtn = true,
        i, l;
    if (array_a.length === array_b.length) {
        for (i = 0, l = array_a.length; (i < l) && rtn; i += 1) {
            rtn = array_a[i] === array_b[i];
        }
    } else {
        rtn = false;
    }
    return rtn;
},
indexOfSimilarArray = function (arrayToFind, arrayToSearch) {
    var i = arrayToSearch.length,
        chk = false;
    while (i && !chk) {
        i -= 1;
        chk = compare_arrays(arrayToFind, arrayToSearch[i]);
    }
    return i;
};

// Test
var myArr = [1,3];
var prizes = [[1,3],[1,4]];
indexOfSimilarArray(myArr, prizes);

JSFiddle: http://jsfiddle.net/guypursey/V7XpE/. (Просмотрите консоль, чтобы увидеть результат.)

Ответ 7

function doesArrayOfArraysContainArray (arrayOfArrays, array){
  var aOA = arrayOfArrays.map(function(arr) {
      return arr.slice();
  });
  var a = array.slice(0);
  for(let i=0; i<aOA.length; i++){
    if(aOA[i].sort().join(',') === a.sort().join(',')){
      return true;
    }
  }
  return false;
}

Стоит отметить:

  • aOA[i].sort().join(',') === a.sort().join(',') - полезный способ проверки массивов, которые содержат одни и те же значения в одном порядке, но являются ссылками на разные объекты.

  • array.slice(0) создает нереляционную копию исходного 2D-массива.

  • Однако для создания копии 3D-массива arrayOfArrays.slice(0) не работает; ссылочная цепочка будет по-прежнему присутствовать. Для создания нереляционной копии необходима функция .map.

Если вы не создадите эти копии без ссылок, вы можете столкнуться с трудностями при поиске проблем. Эта функция должна работать как условная и не влиять на исходные объекты, которые были переданы.

Javascript - одна непостоянная любовница.