Home > Blockchain >  Rails merge array into array of arrays
Rails merge array into array of arrays

Time:08-24

I'm new to Ruby on Rails and I have a weird array situation that I'm unable to figure out how to execute efficiently.

I have this starting array of arrays:

[["6884", true], ["8456", false], ["5631", false]]

Then I have another 1D array:

["6884", "8023", "9837"]

I want to merge the 1D array into the array of arrays by appending the value to the end of the array at the same index in the 2D array.

So the final product should be:

[["6884", true, "6884"], ["8456", false, "8023"], ["5631", false, "9837]]

So the value at index 0 in the 1D array is appended to the end of the array at index 0 in the 2D array, and so on for each element in the 1D array. Is there an easy Ruby way to accomplish this?

CodePudding user response:

You can do it with zip and flatten methods like this:

a = [["6884", true], ["8456", false], ["5631", false]]
b = ["6884", "8023", "9837"]

a.zip(b)
# [[["6884", true], "6884"], [["8456", false], "8023"], [["5631", false], "9837"]]

# Then use flatten to this array:
a.zip(b).map(&:flatten)
# [["6884", true, "6884"], ["8456", false, "8023"], ["5631", false, "9837"]]

CodePudding user response:

Further to Mehmet Adil İstikbal's answer, here's another approach -- just to show that There's More Than One Way To Do It:

a = [["6884", true], ["8456", false], ["5631", false]]
b = ["6884", "8023", "9837"]

a.map.with_index { |item, index| item.push(b[index]) }
# => [["6884", true, "6884"], ["8456", false, "8023"], ["5631", false, "9837"]]

CodePudding user response:

a2 = [["6884", true], ["8456", false], ["5631", false]]
a1 = ["6884", "8023", "9837"]
a2.zip(a1).map { |e2, e1| [*e2, e1] }

or, to avoid the creation of the temporary array a2.zip(a1),

a1.each_index.map { |i| [*a2[i], a1[i]] }

Both return

[["6884", true, "6884"], ["8456", false, "8023"], ["5631", false, "9837"]]

Note that neither expression mutates a2 or a1. See Array#each_index (which, without a block, returns an enumerator) and Enumerable#map.

CodePudding user response:

If you want to modify the first array you can pass a block to zip to append the latter elements to the corresponding sub-array:

a = [["6884", true], ["8456", false], ["5631", false]]
b = ["6884", "8023", "9837"]

a.zip(b) { |ary, el| ary << el }

a
# => [["6884", true, "6884"], ["8456", false, "8023"], ["5631", false, "9837"]]
  •  Tags:  
  • ruby
  • Related