Subtraction between elements in Ruby array

Asked

Viewed 41 times

-1

Hello, I have an array of values:

values = [3, 5, 12, 1, 2]

I would like in the first iteration all elements of the array to be subtracted by the first element (Ex, 5-3, 12-3, 1-3, 2-3)

# [2, 9, -2, -1]

In the second iteration (Ex, 12-5, 1-5, 2-5)

# [7, -4, -3]

In the third iteration (Ex, 1-12, 2-12)

# [-11, -10]

And so on. Subtraction must occur from the later element. I have done the following:

values.map do |price|
 values.map do |value| 
  value - price 
 end 
end

# [[0, 2, 9, -2, -1], [-2, 0, 7, -4, -3], [-9, -7, 0, -11, -10], [2, 4, 11, 0, 1], [1, 3, 10, -1, 0]]

I need: [2, 9, 7,-2, -1, 7, -4, -3, -11, -10, 1]

I leave my thanks for all help, tip and attention so that I can accomplish the desired operation. Thank you!

  • 1

    From what I understand at each iteration you take the first element of the array, subtract it from each of the other elements and remove it from the array. Although you have said "and so on" I assume the iteration stops when a single element remains in the array. You haven’t explained how to treat two-dimensional arrays and whether what you set as "need" is the expected result for the existing entry after the "#".

1 answer

0

I was kind of guessing (as commented, the explanation could have been clearer) but I believe that’s what you want:

values = [3, 5, 12, 1, 2]

(0...values.size).flat_map do |i|
  values[i+1..-1].map { |x| x - values[i] }
end

# => [2, 9, -2, -1, 7, -4, -3, -11, -10, 1]

Split:

0...values.size is a Range, representing the range [0, values.size) (open on the right). This corresponds to a discrete interval over the array indices. Being a Range, the value is also a Enumerable, then we have access to the function flat_map, which in a simplified form is equivalent to a map followed by a Flatten.

In the flat_map, each iteration returns an array in the form you described: starting at an index i, we consider the subarray of i+1 to the end (identified by the index -1) and subtract from each element of that array the value of the element in the index i.

Note that each iteration returns an array, and the flat_map concatenates these arrays. We could do the same thing with map and flatten thus:

values = [3, 5, 12, 1, 2]

iterations = (0...values.size).map do |i|
  values[i+1..-1].map { |x| x - values[i] }
end

# iterations => [[2, 9, -2, -1], [7, -4, -3], [-11, -10], [1], []]

iterations.flatten

# => [2, 9, -2, -1, 7, -4, -3, -11, -10, 1] 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.