1

Is there a way to modify particular array elements (based on some condition) while traversing it in reverse order in Ruby?

To be more clear lets say,

problem is replace even numbers in [1,2,3,4,5] with x

output should be [1,x,3,x,5] (same array) but replace should happen from right to left..traversing from 5 to 1.

Thanks in Advance!

This works: (arr.length -1).downto(0) { |x| do something with arr[x] }

7
  • You mean like collect! but in reverse ? Commented Sep 3, 2012 at 11:11
  • yes exactly, i have noticed that map, collect work from left to right because they in turn depend on each but i want to modify from right to left..i just want to know is there any existing way to do it instead of writing custom code. to traverse we have reverse_each but couldn't find anything to modify :( Commented Sep 3, 2012 at 11:18
  • 1
    is there a reason you cant just use my_array.reverse.map{} ? if you want to put it back in order again just add another .reverse to the end Commented Sep 3, 2012 at 11:24
  • but you don't want the output reserved, right? only the traverse order must be in reverse? and you want the updates always in-place? Commented Sep 3, 2012 at 11:55
  • @Isotope reverse is an additional performance overhead which i want to avoid. Commented Sep 3, 2012 at 11:57

3 Answers 3

3
p [1,2,3,4,5].reverse_each.map{|e| e.odd? ? e : e/2} #[5, 2, 3, 1, 1]
Sign up to request clarification or add additional context in comments.

1 Comment

but this reverses the array and it's not inplace, I think that's what the OP wanted.
1

I understand you want to traverse in reverse order, not get the output also reversed. Maybe this:

xs = [1, 2, 3]
xs.reverse_each.with_index { |x, idx| xs[xs.size-1-idx] = x.to_s if x == 2 }
xs #=> [1, "2", 3]

5 Comments

xs won't look like you show when using map instead of map!.
@Michael: oops, yes, it's a enumerator... uhhmm, maybe with each.
@tokland Thanks! It works :) I couldn't think of it because i wanted to avoid index based access..Looks like it cant be avoided.
@tokland But should be careful while using this because the index starts from 0 lets say your x is 3 but if u try replacing using xs[idx] 1 is modified because ur idx for x = 3 is 0 in this case..please correct me if i am wrong :)
indeed, fixed, the index must be also "reversed"
0

I appreciate and love Ruby's humane syntax, but you may want to consider more verbose options such as:

ary = [1,2,3,4,5]
i = ary.count - 1
while i >= 0 do
    ary[i] = "x" if ary[i] % 2 == 0
    i -= 1
end
puts ary.join(",")

Comments

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.