我有一个包含嵌套数组的数组,看起来像这样:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
当我尝试查找数组tw
是否包含传入的数组时,我总是得到-1的结果。
例如:
var test = $.inArray([3, 0], tw);
var test2 = tw.indexOf([3, 0]);
即使数组中的第一个对象是[3,0]
,两者都返回-1。如何判断特定的数组是否包含在我的数组中?
哦,目前我只在IE9上测试过。
我有一个包含嵌套数组的数组,看起来像这样:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
当我尝试查找数组tw
是否包含传入的数组时,我总是得到-1的结果。
例如:
var test = $.inArray([3, 0], tw);
var test2 = tw.indexOf([3, 0]);
即使数组中的第一个对象是[3,0]
,两者都返回-1。如何判断特定的数组是否包含在我的数组中?
哦,目前我只在IE9上测试过。
那是因为你在寻找不同的对象。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
for...in
。抱歉。是的,那绝对是一个改进,尽管对于这个特定问题的情况没有任何区别,我认为明确地将数组属性设置为“未定义”会引发麻烦。我会更新我的答案。 - Tim Down数组是对象。[3, 0]并不等同于 [3, 0],因为它们是不同的对象。这就是为什么你的inArray函数失效的原因。
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]) {
// ...
}
条件的调整取决于数组的内容。
对于无限嵌套搜索:
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;
}
注意:
NaN!==NaN
是 true
,以及 typeof null
是 "object"
。 - ajax333221为什么不保持简单呢?
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;
}
这是因为$.inArray
和indexOf
都使用===
进行浅比较。
由于你传递给indexOf
的数组与你的二维数组中的数组在内存中不完全相同,===
返回false。你需要进行深度比较才能正确地找到数组 - 从快速查看jQuery文档来看,这并不可用。
$.inArray
和其他小的更改,但我不确定这是否是jQuery或者你是否想要jQuery解决方案(如果是这种情况,请撤销/改进/拒绝)。 - ajax333221