我正在阅读 The Well-Grounded Rubyist ,并且遇到了额外的信用挑战,没有答案。
class Array
def my_each
c = 0
until c == size
yield(self[c])
c += 1
end
self
end
end
举例说明如何使用my_each
my_times
class Array
def my_each
size.my_times do |i|
yield self[i]
end
self
end
end
指出许多Ruby的迭代器都建立在each
之上,而不是相反。
鉴于以上my_each
,如何在my_times
的实施中使用它?
为清楚起见,之前给出了my_times
实施的一个例子:
class Integer
def my_times
c = 0
until c == self
yield(c)
c += 1
end
self
end
end
5.my_times { |e| puts "The block just got handed #{e}." }
因此,似乎问题肯定意味着在my_each
的实现中使用my_times
。
答案 0 :(得分:3)
要使用my_times
实施my_each
,您需要做的只是在my_each
的数组上调用[0, 1, ..., (x - 1)]
,其中x
是{{} 1}}(整数):
self
P.S。如果你在Enumerable而不是Array上定义了class Integer
def my_times(&block)
(0...self).to_a.my_each do |n|
yield n
end
self
end
end
(比如"真正的" my_each
),你可以从上面的第三行删除each
并直接遍历范围而不是先将Range转换为数组。
答案 1 :(得分:2)
修改:我刚注意到Jordan使用了...
而不是..
来生成正确的输出;有关范围差异的更多详细信息,请参阅此answer。我在下面更新了我的答案。
我的帐户太新了,我无法评论Jordan的解决方案;我看到这是大约一年前发布的,但我目前正在阅读 The Well-Grounded Rubyist 并希望对该解决方案发表评论。
我以与Jordan 类似的方式接近相比是关闭的; 产生的相同的 ,但发现输出与my_times
的有根据的Rubyist 实现:
puts 5.my_times { |i| puts "I'm on iteration # {i}!" }
I'm on iteration 0!
I'm on iteration 1!
I'm on iteration 2!
I'm on iteration 3!
I'm on iteration 4!
Jordan的解决方案输出:
puts 5.my_times { |i| puts "I'm on iteration # {i}!" }
I'm on iteration 0!
I'm on iteration 1!
I'm on iteration 2!
I'm on iteration 3!
I'm on iteration 4!
I'm on iteration 5!
我使用了一个神奇的数字来匹配 The Well-Ground的Rubyist 输出 [参见Jordan的解决方案,使用...
代替..
,这样就无需使用幻数]
class Integer
def my_times
(0..(self-1)).to_a.my_each do |n|
yield n
end
self
end
end
答案 2 :(得分:2)
为了实现my_times,我们需要一个数组来发送my_each消息。在本书的那一点上,我不认为范围是覆盖的,所以我在不使用范围的情况下实现。这是解决方案:
require_relative "my_each"
class Integer
def my_times
array = Array.new(self)
c = 0
array.my_each do
array[c] = c
yield(c)
c += 1
end
self
end
end