注入嵌入条件...可能吗?

时间:2013-08-29 23:52:49

标签: ruby-on-rails ruby iterator inject

我期待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

显然有九次出现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

看起来count的{​​{3}}可能不接受阻止?虽然我可能会读错了或者看错了地方......

2 个答案:

答案 0 :(得分:3)

user2246674是正确的,if语句返回nil,但是应该总是返回acc你可以使用turnery操作符来轻松实现

dfs = p.disk_items.inject(0) { |acc, di| di.type == "DiskFile" ? acc + 1 : acc  }

答案 1 :(得分: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 ==“DiskFile”}