3

I have two nested arrays with equal size:

Array1 =[[1, 2], [], [2, 3]]
Array2= [[1, 4], [8, 11], [3, 6]]

I need to merge them in one array, like this:

Array = [[1,2,1,4], [8,11], [2,3,3,6]],

so each elements of new Array[x] = Array1[x] + Array2[x]

I understand how to do it with for(each) cycle, but I am sure Ruby has an elegant solution for that. It is also possible that the solution will produce by changing Array1.

iknow
  • 8,358
  • 12
  • 41
  • 68
a5zima
  • 84
  • 1
  • 6

3 Answers3

4
Array1.each_index.map { |i| Array1[i] + Array2[i] }
  #=> [[1,2,1,4], [8,11], [2,3,3,6]]

This has the advantage that it avoids the creation of a temporary array [Array1, Array2].transpose or Array1.zip(Array2).

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • This answer can also can be easily generalized to more than 2 arrays, or to arrays with more complex (arrays of hashes, etc), while preserving the clarity of the code. – Timur Shtatland Aug 10 '20 at 15:23
3
[Array1, Array2].transpose.map(&:flatten) 
=> [[1, 2, 1, 4], [8, 11], [2, 3, 3, 6]]

RubyGuides: "Turn Rows Into Columns With The Ruby Transpose Method"


Each step explained:

[Array1, Array2]
=> [[[1, 2], [], [2, 3]], 
    [[1, 4], [8, 11], [3, 6]]]

Create a grid like array.

[Array1, Array2].transpose
=> [[[1, 2], [1, 4]], [[], [8, 11]], [[2, 3], [3, 6]]]

transpose switches rows and columns (close to what we want)

[Array1, Array2].transpose.map(&:flatten)
=> [[1, 2, 1, 4], [8, 11], [2, 3, 3, 6]]

flatten gets rid of the unnecessary nested arrays (here combined with map to access nested arrays)

Sebi
  • 398
  • 3
  • 10
3

I would do something like:

array1 =[[1, 2], [], [2, 3]]
array2= [[1, 4], [8, 11], [3, 6]]

array1.zip(array2).map(&:flatten)
# => [[1, 2, 1, 4], [8, 11], [2, 3, 3, 6]]
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • 1
    While a bit wordier, I feel that `array1.zip(array2).map{|a, b| a + b}` better expresses the intent. – Sergio Tulentsev Aug 10 '20 at 13:07
  • 2
    And then we ask ourselves the two questions I've been asking myself for over 15 years: why does `zip` with a block first zip the two elements and then yield the combined array instead of yielding the two elements separately, and why does `zip` with a block act as a side-effecting loop instead of as a transformer. Because then, `Array1.zip(Array2, &:+)` would work, exactly like everybody who uses `zip` the first time *thinks* it would work and is then surprised that it doesn't :-D – Jörg W Mittag Aug 10 '20 at 13:13