制作地图! 调查员做我想做的事
有arrays
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
构成了一个后门:
e.each { 42 } a #=> [42, 42, 42, 42]
我想知道,如何逐步实现这一点,除了零以外的值。 (正如我之前所示,我可以使用e.rewind
和e.next
逐渐用nils填充它。
制作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]
从引用来看,似乎Enumerator #next不接受块,因此不会影响您的next
调用。 如果你只想在清除所有其他元素的同时将最后一个元素加倍,请做一些类似的事情,考虑直接逼近(比如a = a[0..-2].map!{|x| nil} + [a.last*2]
,也许更优雅)。 无论如何,你能不能给我们提供一个更详细的用例,以确保你正在做你真正需要的东西?
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]