2016-02-04 37 views
1

我有这样的代码这样(我经常碰到这种方法签名,那我从Java未来的小白):红宝石重构散列循环方法的返回

def totals 
    t = 0 
    @data.each do |k, v| 
     t += v['totals'].to_i 
    end 
    t 
    end 

@data是哈希散列,每个内部散列值都有一个totals密钥。正如你所看到的,我总结了所有的总数。

这可以用不同的风格进行简化或编程(我相信!这是RUBY的后续)?为什么我需要实例化t?我不能直接从每个循环返回t而没有最后的条件吗?

它只是不觉得干净! 哦等一下!我只记得块,但我会等你的答案...

UPDATE:

的数据结构是这样:

{ typeA: { items: [], totals: "10" }, typeB: { items: [], totals: "23" }} 

我使用Rails!因此,如果Rails的特殊功能超越了Ruby的红色堆栈,那么它们也将非常棒!

回答

5

不同的,因为你已经表明,你正在使用Ruby on Rails的,你可以利用Active支持的Enumerable#sum方法:

def totals 
    @data.sum {|_,v| v['totals'].to_i } 
end 
+0

接受更好的API参考,并提及Nermin的ActiveSupport,它的速度提高了6秒!强硬的呼唤! – mahatmanich

+0

什么是'| _,v |',这是哈希的一些约定,但没有使用密钥? – mahatmanich

+2

@mahatmanich对于未使用的变量,在块中使用'_'表示法 –

4

使用inject

def totals 
    @data.inject(0) do |t, (_, v)| 
    t + v['totals'].to_i 
    end 
end 
3
@data.map{ |_, v| v['totals'].to_i }.inject(:+) 

甚至更​​短:

@data.map{ |_, v| v['totals'].to_i }.sum 
+0

似乎不起作用。它是哈希散列{类型:{项目:[],总数:XYX}} – mahatmanich

+0

@mahatmanich好的,我的误解。编辑答案相应 –

+1

不要忘记建议使用'reduce'的别名''' – lx00st

4

使用Enumerable sum

def totals 
    @data.sum { |_,v| v['totals'].to_i } 
end 

你也可以有起始值从0

def totals(start_value= 0) 
    @data.sum(start_value) { |_,v| v['totals'].to_i } 
end 
+2

官方文档可以在http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum – Stefan

+0

找到。有没有必要“**编辑:**”。此外,我不认为编辑的主题确实增加了有用的东西。简单地提供文档的参考资料 - 涵盖了这一点,并且本身是有用的 - 就足够了。 –

4

在Rails 5,你可以采取的一些优势Enumerable#pluck

h.values.pluck(:totals).map(&:to_i).sum 
+1

还没有,但谢谢你的见解! – mahatmanich

+1

缺点是,这会创建三个临时阵列,但是它的读数非常好,通过多个简单的步骤便于测试。在我看来,如果'h'不大,这种方法有很多优点。 –

+0

不知道你可以使用'pluck'与其他对象,即AR。很好,+1 –