制作地图! 调查员做我想做的事

有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.rewinde.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]