我正在使用JavaScript,并想检查阵列数组中是否存在数组。
这是我的代码,以及返回值:
var myArr = [1,3];
var prizes = [[1,3],[1,4]];
prizes.indexOf(myArr);
-1
为什么呢?
在jQuery中也一样:
$.inArray(myArr, prizes);
-1
当元素出现在数组中时,为什么返回-1?
答案 0 :(得分:21)
您可以使用此
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');
}
答案 1 :(得分:7)
因为[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 :(得分:3)
因为这两种方法在对象上操作时都使用引用相等性。存在的数组和您要搜索的数组可能在结构上相同,但它们是唯一的对象,因此它们不会相等。
这会产生预期的结果,即使它在实践中没用:
var myArr = [1,3];
var prizes = [myArr,[1,4]];
prizes.indexOf(myArr);
要做你想做的事,你需要编写代码,以递归方式显式地比较数组的内容。
答案 3 :(得分:1)
因为javascript对象是通过身份而非价值进行比较的。因此,如果他们不引用同一个对象,他们将返回false。
您需要递归比较才能正常工作。
答案 4 :(得分:0)
首先为数组定义比较函数
// attach the .compare method to Array's 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;
}
第二个只用
找到数组prizes.filter(function(a){ return a.compare(myArr)})
注意:检查array.filter
的浏览器兼容性答案 5 :(得分:0)
假设你只处理一个二维数组(你提到了一个“数组数组”,但没有比这更深),这个非递归代码应该做你需要的。
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/。 (查看控制台以查看结果。)
答案 6 :(得分:0)
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是一个善变的情妇。
答案 7 :(得分:0)
您可以使用Array#some
迭代数组的数组,然后使用Array#every
用单个数组检查内部数组的每一项。
var array = [1, 3],
prizes = [[1, 3], [1, 4]],
includes = prizes.some(a => array.every((v, i) => v === a[i]));
console.log(includes);
答案 8 :(得分:0)
不是 js 专家,只是想出了如何使用 Array.every
和 Array.some
要查找匹配项的索引:
let anarr = ['a',1, 2]
let arrofarrs = [['a',1, 2], [2,3,4]]
arrofarrs.map(
subarr => subarr.every(
(arr_elem, ind) => arr_elem == anarr[ind]
)
)
// output
// Array [ true, false ]
并检查 true
/false
是否包含子数组,只需将 map
更改为 some
arrofarrs.some(
subarr => subarr.every(
(arr_elem, ind) => arr_elem == anarr[ind]
)
)
// output
// true
ofc 仅适用于单层嵌套,但可以递归 ;)
答案 9 :(得分:0)
使用 js Maps,将数组的散列作为键,将实际数组作为值, 如果您需要遍历所有数组,您可以执行 map.values()。 如果您需要查看数组是否存在,只需计算散列 o(n) 并查找 o(1)。
散列函数可以像用 '-' 连接所有元素一样简单,如果您的数组很大,请从该数组中创建一个数字 ([1,2] => 12) ,并使用大素数的 mod编号,用于碰撞链接。
答案 10 :(得分:-1)
function checkArrayInArray(arr, farr){
if(JSON.stringify(arr).includes(JSON.stringify(farr))) return true;
return false;
}