8

I have this 2D array:

arr = [[1,2],[3,4]]

I usually do:

CSV.open(file) do |csv| 
  arr.each do |row| 
    csv << row
  end
end

Is there any easier or direct way of doing it other than adding row by row?

SwiftMango
  • 15,092
  • 13
  • 71
  • 136
  • See also: http://stackoverflow.com/questions/4822422/output-array-to-csv-in-ruby – Phrogz Jun 05 '12 at 19:56
  • 1
    What you have is already pretty darn easy for you the programmer. Are you (prematurely) worried about the performance of adding the rows one at a time? – Phrogz Jun 05 '12 at 20:01
  • @Phrogz No I am not worrying about performance. I wanna make life easier but not sure if there is already something I can use or i will have to do it myself. – SwiftMango Jun 05 '12 at 20:53
  • Like CSV.read method, it can read csv file and parse to a 2D array, but why there is no inverse of that? – SwiftMango Jun 05 '12 at 20:55
  • In older versions of Ruby there used to be CSV.dump...it's gone now – Subimage Jul 30 '16 at 04:27

2 Answers2

10

Assuming that your array is just numbers (no strings that potentially have commas in them) then:

File.open(file,'w'){ |f| f << arr.map{ |row| row.join(',') }.join('\n') }

One enormous string blatted to disk, with no involving the CSV library.

Alternatively, using the CSV library to correctly escape each row:

require 'csv'
# #to_csv automatically appends '\n', so we don't need it in #join
File.open(file,'w'){ |f| f << arr.map(&:to_csv).join } 

If you have to do this often and the code bothers you, you could monkeypatch it in:

class CSV
  def self.dump_array(array,path,mode="rb",opts={})
    open(path,mode,opts){ |csv| array.each{ |row| csv << row } }
  end
end
CSV.dump_array(arr,file)
jaredsmith
  • 7,306
  • 3
  • 20
  • 31
Phrogz
  • 296,393
  • 112
  • 651
  • 745
0

Extending the answer above by @Phrogz, while using the csv library and requiring to change the default delimiter:

File.open(file,'w'){ |f| f << arr.map{|x| x.to_csv(col_sep: '|')}.join }