我在理解 Ruby 中的枚举器时遇到了麻烦。
请纠正我如果我错了,o.enum_for(:arg)
方法应该将对象转换为 Enumerator,并且每次对对象 o
的迭代都应该调用 arg
方法?
令我困惑的是这行代码是如何工作的
[4, 1, 2, 0].enum_for(:count).each_with_index do |elem, index|
elem == index
end
它应该计算有多少元素等于它们在数组中的位置,并且它可以工作。但是,我不明白实际发生了什么。
each_with_index
是否在每次迭代中都调用 count 方法?如果有人可以解释,那就太好了。 最佳答案
来自编程 Ruby:
因此,枚举器访问每个元素,如果块返回 true,则将计数加 1,在这种情况下,这意味着元素是否等于数组索引。
我还没有看到这种模式使用得太多(如果有的话)——我更倾向于:
[4, 1, 2, 0].each_with_index.select { |elem, index| elem == index }.count
编辑
让我们看一下您评论中的示例:
[4, 1, 2, 0].enum_for(:each_slice, 2).map do |a, b|
a + b
end
each_slice(2)
一次获取数组 2 个元素,并为每个切片返回一个数组:[4, 1, 2, 0].each_slice(2).map # => [[4,1], [2,0]]
对结果调用
map
可以让我们对每个子数组进行操作,并将其传递到一个块中:[4, 1, 2, 0].enum_for(:each_slice, 2).map do |a,b|
puts "#{a.inspect} #{b.inspect}"
end
结果是
4 1
2 0
a
和 b
通过块参数“splatted”获得它们的值:a, b = *[4, 1]
a # => 4
b # => 1
您也可以将数组切片作为参数:
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| puts "#{a.inspect}"}
[4, 1]
[2, 0]
这可以让你做到这一点:
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| a.inject(:+) } #=> [5,2]
或者,如果您有 ActiveSupport(即 Rails 应用程序),
[4, 1, 2, 0].enum_for(:each_slice, 2).map {|a| a.sum }
在我看来,这比原始示例要清楚得多。
关于ruby - Ruby 中的枚举器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13350207/