0

Given the arrays:

arrayA = ["1a","2a","3a", ...]
arrayB = ["1b","2b","3b", ...]
arrayC = ["1c","2c","3c", ...]

I want to create a CSV file such as

"1a", "1b", "1c"
"2a", "2b", "2c"
"3a", "3b", "3c"
etc..

How do I do that in Ruby ?

1
  • Did you have a look at the Ruby CSV docs? What did you try so far? Commented May 20, 2020 at 13:26

2 Answers 2

2

transpose does the heavy lifting:

require "csv"
arrayA = ["1a","2a","3a"]
arrayB = ["1b","2b","3b"]
arrayC = ["1c","2c","3c"]

arrs = [arrayA, arrayB, arrayC]

CSV.open("test.csv", "wb") do |csv|
  arrs.transpose.each do |row|
    csv << row
  end
end

test.csv will look like:

1a,1b,1c
2a,2b,2c
3a,3b,3c

Sign up to request clarification or add additional context in comments.

Comments

1

To get the data you want, and assuming you don't care about duplicates, you can sort a joined array and then use Enumerable#each_slice to pass three values at a time (to represent your rows) to your CSV writer:

sorted_data = (arrayA + arrayB + arrayC).sort
sorted_data.each_slice(3) do
  # append elements to your CSV object, or
  # directly to the CSV file
end

There's a potential edge case: if you don't have a merged array that's evenly divisible by 3, your last line may have less than three elements in it. Plan accordingly.

4 Comments

This is exactly what I was looking for!! I tried it and it works great! Many thanks for your precious help.
Henri, I'm not convinced this produces the result you are looking for (despite your insistence that it does). If arrayA = [6,3,5]; arrayB = [1,7,4]; arrayC = [9,3,8] this will produce a CSV file which, when read, will return the array [[1, 3, 3], [4, 5, 6], [7, 8, 9]]. Is that what you want? Another interpretation of your question is reflected in @steenslag's answer, namely, that you want the ith row of the CSV file to represend the array [arrayA[i], arrayB[i], arrayC[i]]. For my example steenslag's solution would have CSV.read return the array [[6, 1, 9], [3, 7, 3], [5, 4, 8]].
@CarySwoveland I'm not sure why you think this creates nested arrays, since (arrayA + arrayB + arrayC).sort #=> ["1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c"].
@CarySwoveland Also note that in this case, #each_slice may pass an Array or a String, depending on how many arguments the block takes, and whether or not the block destructures the argument(s). Other answers may address the optional use of CSV or FasterCSV, or some other custom writers, but grabbing groups of 3 elements at a time from a merged array works as described.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.