You haven’t said what is to be done with the first and last elements of the array, which do not have both a previous and next element. I assume the first element is to be replaced with the next element and the last element is to be replaced by the previous element. This assumes the array has at least two elements, which reflects another weakness in the problem description.
Let
arr = [1,2,3,4]
The direct way of doing that would be:
arr.each_index.map do |i|
case i
when 0
arr[1]
when arr.size - 1
arr[-2]
else
arr[i-1]*arr[i+1]
end
end
#=> [2, 3, 8, 3]
Another way, that I prefer, is to use the method Enumerable#each_cons:
[1, *arr, 1].each_cons(3).map { |p,_,n| p*n }
#=> [2, 3, 8, 3]
Here
a = [1, *arr, 1]
#=> [1, 1, 2, 3, 4, 1]
enum = a.each_cons(3)
#=> #<Enumerator: [1, 1, 2, 3, 4, 1]:each_cons(3)>
We can see the elements enum
will pass to its block by converting it to an array:
enum.to_a
#=> [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 1]]
I’ve used an underscore to represent the second block variable to signify that it is not used in the block calculation. That is a widely-used convention.