bra*_*rad 11 ruby ruby-on-rails inject
我正在创建一个rails应用程序,并在我的一个方法中使用了此代码
item_numbers.inject(0) {|sum, i| sum + i.amount}
Run Code Online (Sandbox Code Playgroud)
item_numbers是我的item_numbers表中的一个对象数组.我应用于它们的.amount方法在一个单独的表中查找item_number的值,并将其作为BigDecimal对象返回.显然,inject方法然后添加所有返回的i.amount对象,这很好用.
我只是好奇为什么当我把这句话写成时它不起作用
item_numbers.inject {|sum, i| sum + i.amount}
Run Code Online (Sandbox Code Playgroud)
根据我可信赖的镐书,这些应该是等价的.是因为i.amount是BigDecimal吗?如果是这样,为什么它现在有用?如果没有,那么为什么它不起作用.
fl0*_*00r 17
我们在API中可以阅读的内容:
如果没有为memo显式指定初始值,则使用collection的第一个元素作为memo的初始值.
因此item_numbers [0]将被指定为初始值 - 但它不是数字,而是一个对象.所以我们遇到了错误
未定义的方法`+'.
所以我们必须将初始值指定为0
item_numbers.inject(0){| sum,i | 总和+ i}
这是因为你正在访问i.amount
而不是简单的访问i
.在不起作用的版本中,你是隐含的item_numbers[0] + item_numbers[1].amount + ...
.
一种简写是item_numbers.map(&:amount).inject(&:+)
,但是如果map
不返回枚举器,那么这种方式可能导致列表上的两次迭代.
如果这没有说服你,如果我们amount
在Fixnum上定义一个方法,在返回之前打印该值,请查看打印出来的内容:
irb(main):002:1> def amount
irb(main):003:2> puts "My amount is: #{self}"
irb(main):004:2> return self
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> [1,2,3].inject { |sum, i| sum + i.amount }
My amount is: 2
My amount is: 3
=> 6
irb(main):008:0> [1,2,3].inject(0) { |sum, i| sum + i.amount }
My amount is: 1
My amount is: 2
My amount is: 3
=> 6
irb(main):009:0>
Run Code Online (Sandbox Code Playgroud)
我们可以清楚地看到,amount
当未明确传入起始值时,第一个元素上没有调用.
归档时间: |
|
查看次数: |
7995 次 |
最近记录: |