2013-04-14 11 views
18

特定の条件をクリアする配列のすべての要素を削除するjavascriptでメソッドを実装する方法について、私はどう思っていましたか? (好ましくはjQueryを使用しないで)javascript - 条件で配列要素を削除

Ex。

ar = [ 1, 2, 3, 4 ]; 
ar.removeIf(function(item, idx) { 
    return item > 3; 
}); 

上記アレイ内の各項目を通過し、これらすべてを除去するであろうという条件のreturn true(この例では、アイテム> 3)。

私はちょうどjavascriptで始まり、誰かがこれを行うための短時間の効率的な方法を知っているのだろうかと思っていました。 更新 - -

条件は同様にオブジェクトのプロパティに取り組むことができればそれはまた素晴らしいことです。

Ex。

item.str == "c"

場合の項目が削除されるだろう

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
ar.removeIf(function(item, idx) { 
    return item.str == "c"; 
}); 

- インデックス条件は同様に動作することができればそれはいいだろう

からアップデート2

Ex。

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
ar.removeIf(function(item, idx) { 
    return idx == 2; 
}); 

答えて

19

filterはあなたのために動作しない場合は、類似した何かをすることArrayに独自のメソッドを追加することができます。

Array.prototype.removeIf = function(callback) { 
    var i = 0; 
    while (i < this.length) { 
     if (callback(this[i], i)) { 
      this.splice(i, 1); 
     } 
     else { 
      ++i; 
     } 
    } 
}; 

私にとって、これはJavaScriptの最もクールな機能の1つです。イアンは同じことをするより効率的な方法を指摘しました。それはJavaScriptのだということを考慮すると、すべてのビットができます:

Array.prototype.removeIf = function(callback) { 
    var i = this.length; 
    while (i--) { 
     if (callback(this[i], i)) { 
      this.splice(i, 1); 
     } 
    } 
}; 

これはあなたではなく、右よりも左にあなたのように動作ようにも、lengthを更新するか、次の項目を引く心配する必要がなくなります。

+0

http://jsfiddle.net/n8JEy/3/これは機能します。 – pickypg

+0

ありがとう、素晴らしい作品。私は、反復処理中にスプライシングによってインデックスの変更がどのように考慮されるのが好きです。 – dk123

+3

これはちょっと面倒です。 http://jsfiddle.net/n8JEy/4/を試してください。そして、2番目のパラメータとしてコールバックに 'i'を渡しませんでした。 – Ian

14

あなたは反対をしArray.filter()を、使用することができます:あなたはArray filter methodを使用することができます

ar.filter(function(item, idx) { 
    return item <= 3; 
}); 
+2

を参照してください。元の式を否定するか、 '<='でなければなりません。 – pickypg

+5

Array.filter()はフィルターされた要素を持つ新しい配列を返しませんか?配列から要素を削除するだけのものはありますか? – dk123

+0

@ dk123:あらかじめ作られたものはありません。 'for'ループを書く必要があります。 – Blender

19

コードは次のようになります

ar = [ 1, 2, 3, 4 ]; 
ar = ar.filter(function(item) { 
    return !(item > 3); 
}); 
1

私はこれらの種類の質問が好きで、私とはちょうど異なるバージョンもあります...条件が

だけでなく、オブジェクトのプロパティに

var ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
var newArray = []; 
for (var i = 0, len = ar.length; i<len; i++) { 
     if (ar[i].str == "b") 
     {newArray.push(ar[i]);}; 
}; 
console.log(newArray); 
を働くことができれば:)

Array.prototype.removeIf = function(expression) { 
    var res = []; 
    for(var idx=0; idx<this.length; idx++) 
    { 
     var currentItem = this[idx]; 
     if(!expression(currentItem)) 
     { 
      res.push(currentItem); 
     } 
    } 
    return res; 
} 

ar = [ 1, 2, 3, 4 ]; 
var result = ar.removeIf(expCallBack); 


console.log(result); 
function expCallBack(item) 
{ 
    return item > 3; 
} 
+0

新しい配列を返すのではなく、要素を実際に削除するためにコードを少し修正(または別のメソッドを追加)してもいいですか?返信いただきありがとうございます。 – dk123

+2

誰でもこれを間違って落とした。これはすべての中から最も良いperfoming答えです。 @Blender jsperf.com/splice-vs-filterでテストを確認してください。最新のバージョンのFirefoxでは少なくとも2倍速く、15倍速く高速です – parliament

2

は、単純に次の例を記述し、以下のIE8かではサポートされていない頭部のアップとして例Live Example

関連する問題