我很好奇如何重构这段代码:
array.collect{|x| x.some_method}.inject(:+) || 0
我用不同的方法在代码中已经有十次了,所以我认为我应该重构,但怎么重构呢?
我尝试了至少十种类型的块、proc和lambda,但在这一点上,我甚至不确定它是否可以重构。
重构如何/到什么?目标是什么?你想/需要超越:
array.collect(&:some_method).inject(:+) || 0
如果唯一更改的是被调用的方法,则将方法符号传递给方法,并在收集期间将其发送给每个对象。
您试图用有问题的代码进行什么通信?看起来像是某种总结;也许是一个简单的以"属性"名称作为参数的sum
方法?
第一次重构:
array.collect(&:some_method).inject(0, :+)
第二次重构,抽象:
module Enumerable
def sum(method)
block_given? ? inject(0) { |acc, x| acc + yield(x) } : inject(0, :+)
end
end
array.map(&:some_method).sum
array.sum(&:some_method)
Ruby习惯用法是:
array.collect(&:some_method).inject(:+)
中使用Symbol#to_proc方法:http://www.ruby-doc.org/core-1.9.3/Symbol.html#method-i-to_prc
您使用array.collect(&:some_method).inject(:+)
作为启动器。你也可以用一个inject
调用来完成,比如:
def my_method(ary, method_symbol)
ary.inject (0) do |sum, elem|
sum + elem.send( method_symbol )
end
end