2014-03-26 38 views
0

我有一个哈希:通过散列迭代而更新一个计数器

students = { 
    class1: 11, 
    class2: 24, 
    class3: 38, 
    class4: 62 
} 

我希望这是四行输出:

1) 11 
2) 35 #11 + 24 
3) 73 #35 + 38 
4) 135 #73 + 62 

它经过的每个元素,并增加了一个值到一个计数器,打印每一次迭代。我需要这样的:

students.each do |key, value| 
    value + counter = total 
    puts total 
end 

但我不知道该怎么做。请指教。

+0

该操作被称为[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-注射) –

回答

0

你实际上相当接近。您需要定义块的total变量外,只使用

total=0 

这将使其留在所有的迭代分配0它。那么你只需要一个小的改变

students.each do |key, value| 
    total=total+value 
    puts total 
end 

它会做你想做的。

切换value + counter = total的顺序很重要,因为分配(通过=)总是分配给左侧的变量。

0

使用你的代码,做了一些小的变化: - 试试这个: -

total = 0 
students.each do |key, value| 
    total += value 
    puts total 
end 
4

有很多方法可以做到这一点,但我会建议的方式,将教你一些不同的事情红宝石。这也是解决这个问题的非常类似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#methodSomeModule#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开头。