2013-02-14 72 views
1

我很好奇,我怎么可能会重构这个代码:如何使用带参数的lambdas来收集数组?

array.collect{|x| x.some_method}.inject(:+) || 0 

我在用不同的方法的代码它的十倍左右,所以我想我应该重构,但如何?

我尝试过至少十种块,过程和lambda,在这一点上我甚至不确定它可以被重构。

+0

考虑的东西更换各种零件 “命名” 等因为'sum' ..名字很好。名称创建隐式文档。如果*相同的行*重复多次,那么这很可能是“名称”的一个好候选。 – 2013-02-14 20:24:45

+0

“重构”类型的问题可能属于http://codereview.stackexchange.com。有关更多信息,请参阅[CodeReview常见问题解答](http://codereview.stackexchange.com/faq#questions)。 – 2013-02-14 20:53:10

回答

2

重构如何/到什么?目标是什么?你想/需要超越:

array.collect(&:some_method).inject(:+) || 0 

如果改变是正在调用该方法的唯一的事情,通过该方法符号的方法和采集期间将其发送到每个对象。

你想与有问题的代码进行沟通?看起来像某种总结;也许一个简单的sum方法与“财产”名称作为参数?

+0

+1表示使用名称。但我不确定我是否会按照提取属性名称的方式进行操作:'sum people.map(&:age)'或类似的东西对我来说很不错。 – 2013-02-14 20:29:49

+0

目标是摆脱这个中间部分,我用明确的命名函数 – 2013-02-15 22:26:42

0

您对于初学者使用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 
1

首先重构:

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)