有一个数组
a = 1, 2, 3, 4
一位普查员:
e = a.map!
然后,通过反复调用e.next
,数组a得到了很好的破坏:
e.next #=> 1
a #=> [1, 2, 3, 4]
e.next #=> 2
a #=> [nil, 2, 3, 4]
e.next #=> 3
a #=> [nil, nil, 3, 4]
那真是太搞笑了!但是当我尝试
时e.next { |x| 2 * x } # => 4
我得到了
a #=> [nil, nil, nil, 4]
而非期望的
a #=> [nil, nil, nil, 8]
我误解了什么?如何让a.map!
做我想要的元素?
我的问题是,我并不完全了解普查员。例如,使用上一代码,枚举器e
构成了a
的后门:
e.each { 42 }
a #=> [42, 42, 42, 42]
我想知道,如何逐步实现这一点,使用除了nil以外的值。 (正如我之前所示,我可以使用e.rewind
和e.next
多次逐渐填充nils。
答案 0 :(得分:3)
要使map!
符合您的要求,您需要使用Enumerator#feed
方法,请考虑
ary = *1..4
enum = ary.map!
# the `loop` method handles `StopIteration` for us
loop do
x = enum.next
enum.feed(x * 2)
end
ary
# => [2, 4, 6, 8]
答案 1 :(得分:2)
从参考文献来看,似乎Enumerator #next不接受某个块,因此不会影响您的next
调用。如果你只想在清除所有其他元素的同时将最后一个元素加倍,做一些类似的事情,考虑直接的方法(比如a = a[0..-2].map!{|x| nil} + [a.last*2]
,也许更优雅)。无论如何,你能不能给我们提供一个更详细的用例,以确保你正在做你真正需要的东西?
答案 2 :(得分:1)
a.map!
接受一个块,但如果没有提供块,则返回一个枚举器。 Enumerator#next
不接受阻止。
您希望使用它来实现目标:
a.map! {|x| x * 2}
如果要将数组中的所有元素乘以2。
有关下一步的信息,请查看http://ruby-doc.org/core-2.0/Enumerator.html#method-i-next
如果您希望输出完全为[nil, nil, nil, 8]
,您可以执行以下操作:
func = lambda { |x|
unless x == 4
nil
else
x * 2
end
}
a.map!(&func) #> [nil, nil, nil, 8]