Проверьте, существует ли массив в массиве массивов?
Я использую 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 - одна непостоянная любовница.