有很多方法可以做到这一点,但我会建议的方式,将教你一些不同的事情红宝石。这也是解决这个问题的非常类似Ruby的方式。
代码
students = {
class1: 11,
class2: 24,
class3: 38,
class4: 62 }
students.reduce(0) do |tot, (k,v)|
tot += v
puts k[/\d+/] + ") #{tot}"
tot
end
1) 11
2) 35
3) 73
4) 135
说明
我用Enumerable#reduce(又名inject
),因为该方法便于合计数的集合,使用一个变量(这里tot
),其保持块内的运行总数。这正是你需要的。
除此之外:您将学习很多阅读Ruby方法的文档。方法参考如下:SomeClass#method
或SomeModule#method
。这里,reduce
是模块Enumerable
的实例方法。 students
是类Hash
的一个实例,但该类“混入”(包括)模块Enumerable
的实例方法。
对象tot
是一个Fixnum
,它被初始化为reduce
的参数,这里是零。 (如果没有给出初始值,则从student
- 11 - 的初始值将被分配给tot
)。每次执行块中的代码时,块末尾的值将返回给枚举器(这就是为什么tot
在那里)。在枚举接收器students
的所有元素后,tot
的值将返回reduce
(尽管您不会使用它)。
第一次调用块的块变量如下:
tot => 0
k => :class1
v => 11
要打印
1) 11
我想你想的标签1)
是的:class1
右端。要从符号k => :class1
确切得到1
,可以使用方法Symbol#[]和正则表达式/\d+/
,它提取一个或多个数字0-9的字符串(尽可能多)。
在阅读方法Symbol#[]
的文档时,您会看到它将符号:class1
转换为字符串"class1"
,然后调用该字符串上的方法String[]。
自从Ruby 1.9+以来,很多人更喜欢使用Enumerable#each_with_object而不是reduce
。该方法将被用于这样的:
students.each_with_object(0) do |(k,v),tot|
tot += v
puts k[/\d+/] + ") #{tot}"
end
注意,用这种方法,没有必要返回对象(tot
)到枚举的值,并且该tot
是在块的列表的末尾变量,而在reduce
开头。
该操作被称为[http://en.wikipedia.org/wiki/Prefix_sum#Scan_higher_order_function](*Prefix Sum *或* Scan *),这在['Enumerable'](http:///Ruby-Doc.Org/core-2.1.1/Enumerable.html)API。它与[http://wikipedia.org/wiki/Fold_(higher-order_function)](*Fold*)紧密相关,在Ruby中可用[[Enumerable#inject']](http:// Ruby-Doc .ORG /芯-2.1.1/Enumerable.html#方法-I-注射) –