2

多次元配列からnull値を削除する関数を作成しようとしていますが、うまく機能しません。配列の最後のレイヤーには浸透せず、2つのnull値が隣接している場合は削除されません。

function isArray(obj) {
    // http://stackoverflow.com/a/1058753/1252748
    return Object.prototype.toString.call(obj) === '[object Array]';
}

function removeEmptyArrayElements(obj) {

    for (key in obj) {
        if (obj[key] === null) {

            obj = obj.splice(key, 1);

        }
        var isArr = isArray(obj[key]);
        if (isArr) {
            removeEmptyArrayElements(obj[key]);
        }

    }
    return obj;
}
4

2 に答える 2

7

オブジェクトを繰り返し処理している間は、オブジェクトから要素を削除しないでください。

for ... in配列では使用しないでください。

filterやのような高階関数を利用してくださいmap。これを試して:

function removeEmptyArrayElements(arr) { 
   if (!isArray(arr)) {
      return arr;
   } else {
       return arr.filter( function(elem) { 
          return elem !== null
       } ).map(removeEmptyArrayElements)
   }
}

説明:

「高階」関数は、他の関数を値として使用する関数です - それらをパラメータとして受け入れるか、それらを返すか、またはその両方です。この場合、Javascript の Array クラスの 2 つのメソッドを使用しました。このメソッドは、関数をパラメーターとして受け取り、それを使用して新しい配列を作成して返します。

someArray.filter( function はのすべての要素に対して function を呼び出し)関数が trueを返した要素のみを含む新しい配列を返します。この場合に渡した関数は、要素が null でない場合に true を返す無名関数です。したがって、その呼び出しの結果は、すべてのヌルが削除された元の配列です。someArrayfunction(elem) { return elem !== null }filter

次に、それ自体が配列である結果の要素から null を削除します。それに使いmapました。someArray.map( functionも配列のすべての要素で function)を呼び出しますが、それらの結果に基づいて入力のサブセットを返す代わりに、結果自体を返すだけです。たとえば、配列を返します。この場合、渡す関数は、定義中の関数です.. への再帰呼び出しです。[1,2,3].map(function(x){return x*2})[2,4,6]removeEmptyElements

自分自身を呼び出すこの終わりのないサイクルを止める方法が必要です。それがアウターのif目的です。配列ではない要素で呼び出された場合は、それをそのまま返します。

于 2012-05-14T20:14:26.663 に答える
2

削除する配列をループしています。これにより、「2 つの null 値が隣接している場合は削除されません」というバグが発生します。「配列の最後の層まで浸透していません」という部分は、おそらく で値を再割り当てしていないためですobj[key]。配列は、参照ではなく、値によってコピーされます。

私は次のようにします:

function isArray(obj) {
    // http://stackoverflow.com/a/1058753/1252748
    return Object.prototype.toString.call(obj) === '[object Array]';
}

function removeEmptyArrayElements(arr) {
    var i;
    for (i = 0; i < arr.length; i += 1) {
        if (arr[i] === null) {
            arr = arr.splice(i, 1);
            i -= 1; // decrement counter!

        } else if (isArray(arr[i])) {
            arr[i] = removeEmptyArrayElements(arr[i]);
        }
    }
    return arr;
}
于 2012-05-14T20:08:38.167 に答える