2016-05-20 17 views
0

なぜこのテストに合格しないのですか?配列内の配列の値に応じて配列をフィルタリングする方法は?

it('lodash_test', function() { 
    var arr = [{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "33", y: "2"}]}] 
    var result = _.filter(arr, function(obj) { 
     obj.b.forEach(function(item_b) { 
      if(item_b.x=="1") { 
       return true; 
      } 
     }); 
    }); 
    expect(result).to.be.eql([{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}]); 
}); 

答えて

1

forEachの戻り値が完全に無視され、そしてあなたの_.filter述語関数は何も返すことはありませんので。

おそらくsomeを使用したい:

it('lodash_test', function() { 
    var arr = [{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "33", y: "2"}]}] 
    var result = _.filter(arr, function(obj) { 
     return obj.b.some(function(item_b) { 
    // ^^^^^^^  ^^^^ 
      if(item_b.x=="1") { 
       return true; 
      } 
     }); 
    }); 
    expect(result).to.be.eql([{a: "x", b: [{x: "1", y: "2"}]}, {a: "x", b: [{x: "1", y: "2"}]}]); 
}); 

述語がtruthy値を返す最初の時間を停止し、配列内の各エントリの述語を呼び出すArray#some。述部が真理値を返した場合、戻り値はtrue、そうでない場合はfalseです。

私が上記で強調したreturnは、_.filter述語からの返信です。元のreturn truesome(旧:forEach)からの返品です。

+0

あなたは天才です:)ありがとう!ちなみに、それは仕事をするには効果的な方法だと思いますか?より良い選択肢はありますか? – scaryguy

+0

@scaryguy:小さなデータセットの場合、それは問題ではないと思います。シンプルで、仕事を終わらせることができます。パフォーマンスが問題となる場合、パフォーマンスについて心配してください。 :-)データの構造に基づいて、私はあなたがやっていること以外にあなたがそれをどうやってやれるかすぐには分かりません。内側の配列をループして 'x ==" 1 "'を持つかどうかを知る必要があります。 JavaScriptエンジンは、これらの述語呼び出しを最適化しようとしています(たとえそうでなくても、心配する価値はありません)(http://blog.niftysnippets.org/2012/02/foreach-and-runtime- cost.html))。 –

+0

これを広告サーバーに使用します。 MongoDBで同じことをするのではなく、基本レコード数を取得しています。奇数レコードをフィルタリングするために繰り返し処理しています。たぶんそれは "コメント"のための非常に広い質問ですが、これは "dbクエリ"よりも優れているはずだと思いますか?あなたが答えたいなら、私はこれのために別の質問を追加することができます:) – scaryguy

関連する問題