0

期待しています9が、取得 していnilます。理由がわからない。

> dfs = p.disk_items.inject { |acc, di| acc + 1 if di.type == "DiskFile" }
=> nil

同じ問題:

> dfs = p.disk_items.inject(0) { |acc, di| if di.type == "DiskFile" then acc + 1 end } 
=> nil

明らかに、 が真である 9 つのオカレンスがdi.type == "DiskFile"あります。

> dfs = p.disk_items.inject(0) { |acc, di| puts di.type == "DiskFile" }
true
true
true
true
true
true
true
true
true
false
=> nil

私は何を台無しにしていますか?ActiveRecord条件を使用できない場合は、属性の条件を満たす配列内のすべてのオブジェクトをカウントするより良い方法があるかもしれません。

編集:FWIW:

> p.disk_items.class
=> ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_DiskItem

Railsソースのこの実装のように見えますがcount、ブロックを受け入れない可能性がありますか? 私はこれを間違って読んでいるか、間違った場所を見ているかもしれませんが...

4

2 に答える 2

3

user2246674 は正しいです。if ステートメントは nil を返していますが、inject は常に返す必要accがあります。回転演算子を使用すると、これを簡単に行うことができます

dfs = p.disk_items.inject(0) { |acc, di| di.type == "DiskFile" ? acc + 1 : acc  }
于 2013-08-29T23:59:58.313 に答える
1

if「実行しない」場合、ブロックは に評価されnilます。これは最後のケースで発生し、結果 ( nil) が返されます。

考慮してください(ロングハンド):

if di.type == "DiskFile" then
    acc + 1
else
    acc      # so we never return nil
end

さまざまな省略形 (つまり ?:) がありますが、私は . を使用しcount {block}ます。値で何か他のことをする必要がある場合(おそらく、「時々」注入で使用している可能性があります)selectも役立つ場合があります。

p.disk_items.count {|di| di.type == "ディスクファイル"}

于 2013-08-29T23:59:16.997 に答える