9

我有一个带有嵌套数组的数组,如下所示:

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 上测试过它。

4

6 回答 6

13

那是因为您正在寻找不同的对象。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
于 2012-04-21T15:14:30.780 回答
2

数组是对象。[3, 0] 不等于 [3, 0] 因为它们是不同的对象。这就是您的 inArray 失败的原因。

于 2012-04-21T15:16:32.187 回答
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]) {
   // ...
}

可以调整条件的位置取决于数组的内容。

于 2012-04-21T15:26:24.513 回答
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;
}

笔记:

  • 支持无限嵌套数组
  • 正确处理稀疏数组
  • 使用typeof检查

jsFiddle 演示

于 2012-04-21T22:55:41.833 回答
0

这是因为$.inArrayindexOf都使用===.

由于您传递的数组indexOf在内存中与二维数组中的数组不完全相同,因此===返回 false。您需要进行深入比较才能正确找到数组 - 快速浏览一下 jQuery 文档,这在此处不可用。

于 2012-04-21T15:17:57.227 回答
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;
}
于 2015-05-14T02:16:25.503 回答