如何以Ruby的方式在嵌套哈希中添加值

3

这里有一个嵌套的哈希表。我们想要利用ruby的方式将所有“subtotal”的值相加。需要注意的是,在执行加法时,“0”和“1342119042142”的键可以是任何其他未知字符串(键的数量至少为1,可能为多个)。

{"0"=>{"lease_item_id"=>"3",
 "subtotal"=>"100"},
 "1342119042142"=>{"lease_item_id"=>"1",
 "subtotal"=>"100",
 "_destroy"=>"false"}}}

感谢您的选择。

“Ruby的方式”对于Python来说就像“Pythonic”一样毫无意义。对于每种编程语言,我们都应该使用它提供的最习惯和强大的资源,这是理所当然的。 - tokland
3个回答

3

像这样:

设置哈希表:

s = {"0"=>{"lease_item_id"=>"3", "subtotal"=>"100"},
     "1342119042142"=>{"lease_item_id"=>"1", "subtotal"=>"100","_destroy"=>"false"}}

计算总数:

total = s.inject(0) { |i, j| i + j.last["subtotal"].to_i}

解释:在这里查看文档。基本上,inject被赋予一个初始值(在上面的代码中为0),并将该值传递给给定的块,在其中它被设置为每次迭代中从块返回的值。因此,在上述代码中,最初它为0,在第一次迭代中它被设置为0 + 100,现在等于100,在第二次[也是最后一次]迭代中,它被设置为100 + 100,即200。


1
j 是一个数组,因为你正在迭代一个哈希表,它总是给你键/值对。你可以使用 { |i,(k,v)| ... } 并使用 v 代替。而且没有必要使用 +=,因为 inject 将块的值作为下一次迭代中的 i 返回:{ |i,(k,v)| i + v['subtotal'].to_i } - mu is too short
@mikhailvs和mu都太简短了,你们能否解释一下这里的inject是如何工作的,或者指向一些文档?我看到了一些惊人的inject用法,试图理解。但其中的逻辑对我来说仍然不清楚。谢谢。 - user938363
ij太泛泛,变量名应该更加具体描述。更好的写法是:{ |acc, (key, attrs)| acc + attrs["subtotal"].to_i } - tokland

2
假设 h 是您的哈希值,小计可以是十进制值:
h.values.sum{|x| x['subtotal'].to_f}

1
Ruby中的数组没有sum方法。 - HRÓÐÓLFR
1
该问题标记为[ruby-on-rails],sum被添加到了activesupport核心扩展中的Enumerable: http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum。 - Casual Coder
1
然而,OP明确表示他希望以“Ruby的方式”回答。 - HRÓÐÓLFR
在Rails控制台中,以上代码可以正常工作。我应该提到Ruby或Rails的方式。谢谢。 - user938363

1
hash = {"0"=>{"lease_item_id"=>"3", "subtotal"=>"100"}, "1342119042142"=>{"lease_item_id"=>"1", "subtotal"=>"100", "_destroy"=>"false"}} 

sum = hash.values.reduce(0){|sum,inner| sum + inner["subtotal"].to_i } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接