2

I know the idiomatic way to do a for loop in Ruby is to use an Enumerator like .each, but I'm running into a problem: I'd like to iterate over a subset of an Array and modify those elements. Calling .map! with a subset like ary[0..2] or .slice(0..2) doesn't seem to do it; presumably because that slicing operator is creating a new Array?

Desired behavior with for instead of iterator:

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]

Things that don't work:

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]
1
  • thanks for the edit, I must've accidentally clicked that suggested tag. Commented Nov 26, 2013 at 7:49

3 Answers 3

2

Try this.

In example below I implemented something that could be named map_with_index. each_with_index if no block given returns iterator. I use it to map our array.

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]
Sign up to request clarification or add additional context in comments.

Comments

1

You may also try the following:

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

Comments

1

You could use Array#each_index if you don't mind referencing the array twice:

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]

Or if you don't want to iterate the whole array, this would work, too:

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

2 Comments

Does the multiple referencing have a significant effect on speed?
It should be faster in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.