我有一个嵌套数组的数组,如下所示:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
当我尝试查找数组tw
是否包含传入的数组时,我总是得到-1的结果。
例如:
var test = $.inArray([3, 0], tw);
var test2 = tw.indexOf([3, 0]);
都返回-1,即使数组中的第一个对象是[3,0]
如何确定我的数组中是否包含特定的数组数组?
哦,到目前为止我只在IE9上测试过它。
答案 0 :(得分:10)
那是因为你正在寻找一个不同的对象。 indexOf()
使用严格的相等比较(如===
运算符),[3, 0] === [3, 0]
返回false。
您需要手动搜索。下面是一个使用更通用indexOf()
函数的示例,该函数使用自定义比较器函数(评论中@ ajax333221建议改进):
// Shallow array comparer
function arraysIdentical(arr1, arr2) {
var i = arr1.length;
if (i !== arr2.length) {
return false;
}
while (i--) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
function indexOf(arr, val, comparer) {
for (var i = 0, len = arr.length; i < len; ++i) {
if ( i in arr && comparer(arr[i], val) ) {
return i;
}
}
return -1;
}
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
alert( indexOf(tw, [3, 0], arraysIdentical) ); // Alerts 0
答案 1 :(得分:2)
数组对象。 [3,0]不等于[3,0],因为它们是不同的对象。这就是你的inArray失败的原因。
答案 2 :(得分:2)
因为您正在比较两个不同的数组实例。比较对象仅在它们是同一个实例时返回true
,如果它们包含相同的数据则无关紧要。
在您的情况下,您可以使用此方法:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
if (~tw.join(";").split(";").indexOf(String([3, 0]))) {
// ...
}
或类似的东西:
if (tw.filter(function(v) { return String(v) === String([3, 10]) })[0]) {
// ...
}
可以调整条件取决于数组的内容。
答案 3 :(得分:2)
对于无限嵌套搜索:
function indexOfArr(arr1, fnd1) {
var i, len1;
//compare every element on the array
for (i = 0, len1 = arr1.length; i < len1; i++) {
//index missing, leave to prevent false-positives with 'undefined'
if (!(i in arr1)) {
continue;
}
//if they are exactly equal, return the index
if (elementComparer(arr1[i], fnd1)) {
return i;
}
}
//no match found, return false
return -1;
}
function elementComparer(fnd1, fnd2) {
var i, len1, len2, type1, type2, iin1, iin2;
//store the types of fnd1 and fnd2
type1 = typeof fnd1;
type2 = typeof fnd2;
//unwanted results with '(NaN!==NaN)===true' so we exclude them
if (!((type1 == "number" && type2 == "number") && (fnd1 + "" == "NaN" && fnd2 + "" == "NaN"))) {
//unwanted results with '(typeof null==="object")===true' so we exclude them
if (type1 == "object" && fnd1 + "" != "null") {
len1 = fnd1.length;
//unwanted results with '(typeof null==="object")===true' so we exclude them
if (type2 == "object" && fnd2 + "" != "null") {
len2 = fnd2.length;
//if they aren't the same length, return false
if (len1 !== len2) {
return false;
}
//compare every element on the array
for (i = 0; i < len1; i++) {
iin1 = i in fnd1;
iin2 = i in fnd2;
//if either index is missing...
if (!(iin1 && iin2)) {
//they both are missing, leave to prevent false-positives with 'undefined'
if (iin1 == iin2) {
continue;
}
//NOT the same, return false
return false;
}
//if they are NOT the same, return false
if (!elementComparer(fnd1[i], fnd2[i])) {
return false;
}
}
} else {
//NOT the same, return false
return false;
}
} else {
//if they are NOT the same, return false
if (fnd1 !== fnd2) {
return false;
}
}
}
//if it successfully avoided all 'return false', then they are equal
return true;
}
备注:强>
答案 4 :(得分:0)
这是因为$.inArray
和indexOf
都使用===
进行浅层比较。
由于您传递的数组到indexOf
的内存与二维数组中的数组不完全相同,因此===
返回false。您需要进行深入的比较以正确地找到数组 - 从快速浏览一下jQuery文档,这在那里是不可用的。
答案 5 :(得分:0)
为什么不保持简单?
function indexOfCustom (parentArray, searchElement) {
for ( var i = 0; i < parentArray.length; i++ ) {
if ( parentArray[i][0] == searchElement[0] && parentArray[i][1] == searchElement[1] ) {
return i;
}
}
return -1;
}