我想从块中访问枚举器的大小,如下所示:
["cat", "dog", "mouse"].each_with_index { |e, i| puts "#{i + 1} of #{x.size}: #{e}" }
其中x是运行each_with_index的数组。
我尝试了tap方法,但是这并没有像我想象的那样工作。
例如,这段代码似乎没问题,我想:
["cat", "dog", "mouse"].tap { |a| a.each_with_index { |e, i| puts "#{i + 1} of #{a.size}: #{e}" }} # Works, but why do I need two blocks?
我希望只使用一个块,而不是两个块。像这样:
["cat", "dog", "mouse"].each_with_index.tap { |a, e, i| puts "#{i + 1} of #{a.size}" } # Does not work
答案 0 :(得分:3)
那是因为在调用each_with_index时,您可以使用您给出的两个参数在块内工作 - 在这种情况下,是项目及其索引。
通常你可以单独存储数组,然后从块中引用它:
animals = ["cat", "dog", "mouse"]
animals.each_with_index { |e, i| puts "#{i + 1} of #{animals.size}: #{e}" }
并且它有效,有两行代码和一个块,但是你将无法在块中引用你的动物数组。
所以你尝试使用tap似乎是更准确的想法。由于tap会自动生成块,这就是你想要的,然后返回self,你就可以在你的块中执行操作,因为你不需要做任何其他事情。
["cat", "dog", "mouse"].tap do |a|
a.each_with_index do |e, i|
puts "#{i + 1} of #{a.size}: #{e}"
end
end
但为此你需要两个块,一个用于访问自己(["cat", "dog", "mouse"]
),然后在each_with_index
上使用self
。
答案 1 :(得分:2)
Ruby没有这样的方法,但你可以自己构建它:(这是为了演示目的,你通常不应该改变核心类)
class Enumerator
def with_enum
each do |*values|
yield values, self
end
end
end
["cat", "dog", "mouse"].each.with_index(1).with_enum do |(e, i), enum|
puts "#{i} of #{enum.size}: #{e}"
end
请注意enum
是对枚举数的引用,而不是对数组本身的引用。 Enumerator
不会公开它所指的对象。