Modify only first n elements and return the modified array in ruby

Viewed 306

I need to perform an operation on k set of values of an array and return the modified array.

I have an array = [10,32,5,6,7]

Let us say k=2

I am trying to take only the first two elements here by doing:

arr2=[]
array[0..k-1].each do |i|
 res=i.to_f/2.0
 arr2.push(res.round)
end

=>arr2=[5,16]

I want to replace the first 2 elements in the array with arr2 values. How can I achieve this without having to create so many new arrays.

3 Answers

There is no need to iterate the entire array.

array = [10,32,5,6,7]

array[0, 2] = array[0, 2].map { |n| n/2.0 }
array
  #=> [5.0, 16.0, 5, 6, 7] 

or

2.times { |i| array[i] = array[i]/2.0 }
array
  #=> [5.0, 16.0, 5, 6, 7] 

The above reflects my understanding that the original array is to be mutated. If the array is not to be mutated one could write the following.

array[0, 2].map { |n| n/2.0 }.concat(array[2..-1])
  #=> [5.0, 16.0, 5, 6, 7] 
array
  #=> [10, 32, 5, 6, 7] 

You don't need to push to a new array, why not do:

array = [10,32,5,6,7]
k = 2

array[0..k-1].each_with_index do |val, indx|
  array[indx] = val / 2 # or whatever processing really
end

This is a simple way to solve your problem as .each_with_index is doing the work here and allows you to modify the initial array easily. This will output:

[5, 16, 5, 6, 7]

What's wrong with your current implementation? Nothing, you just need to sum the other elements from array:

arr2=[]
array[0..k-1].each do |i|
 res=i.to_f/2.0
 arr2.push(res.round)
end
arr2 + array[k..-1] # [5, 16, 5, 6, 7]
  • Whenever you do integer.to_f / ..., you can do fdiv.
  • Instead of assigning a "memo" array, you can use map:
arr2 = array[0..k-1].map do |i|
  res=i.to_f/2.0
  res.round
end + array[k..-1]
arr2 # [5, 16, 5, 6, 7]
  • Instead of doing k - 1 to get a range, you can use an exclusive range 0...k.

Your code would look like (without modifying array):

array[0...k].map { |i| i.fdiv(2.0).round } + array[k..-1] # [5, 16, 5, 6, 7]
Related