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

时间:2013-11-26 07:15:13

标签: ruby arrays loops iterator

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

使用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]

3 个答案:

答案 0 :(得分:2)

试试这个。

在下面的示例中,我实现了可以命名为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]

答案 1 :(得分:1)

可能也会尝试以下操作:

?> 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]

答案 2 :(得分:1)

如果您不介意两次引用数组,可以使用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]