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

無限ネスト検索の場合:

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 に答える
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]) {
   // ...
}

条件を調整できる場所は、配列の内容によって異なります。

于 2012-04-21T15:26:24.513 に答える
2

配列はオブジェクトです。[3, 0] は異なるオブジェクトであるため、[3, 0] と等しくありません。それがあなたの inArray が失敗する理由です。

于 2012-04-21T15:16:32.187 に答える
0

これは、$.inArrayindexOfの両方が を使用して浅い比較を使用するため===です。

渡す配列はindexOf、2D 配列の配列とメモリ内でまったく同じではないため、===false を返します。配列を適切に見つけるには、詳細な比較を行う必要があります.jQueryドキュメントを一目見ただけで、これは利用できません.

于 2012-04-21T15:17:57.227 に答える