如何在Ruby中迭代修改数组子集



我知道在Ruby中执行for循环的惯用方法是使用类似.each的枚举器,但我遇到了一个问题:我想迭代数组的一个子集并修改这些元素。用像ary[0..2].slice(0..2)这样的子集调用.map!似乎并不能做到这一点;大概是因为切片操作符正在创建一个新的数组?

使用for而不是迭代器的所需行为:

iter_ind = [2,3,4]
my_ary = [1,3,5,7,9,11]
for j in iter_ind
  my_ary[j] = my_ary[j] + 1
  # some other stuff like an exchange operation maybe
end
=> [1, 3, 6, 8, 10, 11]

不起作用的东西:

irb(main):032:0> ar[2..4].map! {|el| el = el+1}
=> [6, 8, 10]
irb(main):033:0> ar
=> [1, 3, 5, 7, 9, 11]
irb(main):034:0> ar.slice(2..4).map! {|el| el = el+1}
=> [6, 8, 10]
irb(main):035:0> ar
=> [1, 3, 5, 7, 9, 11]
irb(main):036:0> ar[2..4].collect! {|el| el = el+1}
=> [6, 8, 10]
irb(main):037:0> ar
=> [1, 3, 5, 7, 9, 11]

试试这个。

在下面的例子中,我实现了一个可以命名为map_with_index的东西。如果没有给定块,则each_with_index返回迭代器。我用它来绘制我们的阵列。

ary = [1, 3, 5, 7, 9, 11]   
ary.each_with_index.map { |elem, index| index.between?(2, 4) ? elem += 1 : elem } 
# => [1, 3, 6, 8, 10, 11]

您也可以尝试以下操作:

?> ary = [1, 3, 5, 7, 9, 11]
=> [1, 3, 5, 7, 9, 11]
?> ary.map!.with_index {|item, index| index.between?(2, 4) ? item += 1 : item}
=> [1, 3, 6, 8, 10, 11]
?> ary
=> [1, 3, 6, 8, 10, 11]

如果不介意引用两次数组,可以使用Array#each_index

ary = [1, 3, 5, 7, 9, 11]
ary.each_index { |i| ary[i] += 1 if i.between? 2, 4 }
#=> [1, 3, 6, 8, 10, 11]

或者,如果你不想迭代整个数组,这也可以:

ary = [1, 3, 5, 7, 9, 11]
ary[2..4] = ary[2..4].map { |el| el + 1 }
ary
#=> [1, 3, 6, 8, 10, 11]

最新更新