我有一个哈希:
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 :(得分:4)
有很多方法可以做到这一点,但我会建议一种方法来教你一些关于Ruby的不同内容。这也是一种非常类似于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
的右端。要从符号1
中精确k => :class1
,您可以使用方法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
的开头。
答案 1 :(得分:0)
你实际上相当接近。您需要在块之外定义total
变量,只需使用
0
total=0
这将使其贯穿所有迭代。
然后你需要做一些小改动students.each do |key, value|
total=total+value
puts total
end
它会做你想要的。
切换value + counter = total
的顺序非常重要,因为作业(通过=
)始终会分配给左侧的变量。
答案 2 :(得分:0)
使用您的代码,做了一些小改动: - 试试这个: -
total = 0
students.each do |key, value|
total += value
puts total
end