Javascript indexOf用于未找到数组的数组数组
我有一个嵌套数组的数组,如下所示:
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上测试过它。
那是因为你正在寻找一个不同的对象。 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
数组是对象 。 [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; }
笔记:
- 支持无限嵌套数组
- 正确处理稀疏数组
- 使用类型检查
jsFiddle演示
这是因为$.inArray
和indexOf
都使用===
进行浅层比较。
由于您传递的数组是indexOf
而不是与2D数组中的数组完全相同,因此===
返回false。 你需要做一个深入的比较才能正确地找到数组 – 从快速浏览一下jQuery文档,这在那里是不可用的。
为什么不保持简单?
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; }