Javascript indexOf用于未找到数组的数组数组

时间:2012-04-21 15:11:00

标签: javascript jquery arrays

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

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

6 个答案:

答案 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;
}

备注:

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

jsFiddle demo

答案 4 :(得分:0)

这是因为$.inArrayindexOf都使用===进行浅层比较。

由于您传递的数组到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;
}