175 votes

Sortie d'un tableau vers CSV en Ruby

Il est assez facile de lire un fichier CSV dans un tableau avec Ruby mais je ne trouve pas de bonne documentation sur la façon d'écrire un tableau dans un fichier CSV. Quelqu'un peut-il me dire comment faire ?

J'utilise Ruby 1.9.2 si cela compte.

307voto

Dylan Markow Points 65796

Vers un fichier :

require 'csv'
CSV.open("myfile.csv", "w") do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

À une chaîne de caractères :

require 'csv'
csv_string = CSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

Voici la documentation actuelle sur le CSV : http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html

34voto

boulder_ruby Points 6257

Je l'ai réduit à une seule ligne.

rows = [['a1', 'a2', 'a3'],['b1', 'b2', 'b3', 'b4'], ['c1', 'c2', 'c3'], ... ]
csv_str = rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join("")
#=> "a1,a2,a3\nb1,b2,b3\nc1,c2,c3\n" 

Faire tout ce qui précède et sauvegarder dans un csv, en une seule ligne.

File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join(""))}

NOTE :

Pour convertir une base de données d'enregistrements actifs en csv, il faudrait faire quelque chose comme ça, je pense.

CSV.open(fn, 'w') do |csv|
  csv << Model.column_names
  Model.where(<<criteria>>).each do |m|
    csv << m.attributes.values
  end
end

Hmm @tamouse, ce gist est un peu confus pour moi sans lire la source csv, mais en général, en supposant que chaque hachage dans votre tableau a le même nombre de paires k/v & que les clés sont toujours les mêmes, dans le même ordre (c'est-à-dire si vos données sont structurées), cela devrait faire l'affaire :

rowid = -1
CSV.open(fn, 'w') do |csv|
  hsh_ary.each do |hsh|
    rowid += 1
    if rowid == 0
      csv << hsh.keys# adding header row (column labels)
    else
      csv << hsh.values
    end# of if/else inside hsh
  end# of hsh's (rows)
end# of csv open

Si vos données ne sont pas structurées, cela ne fonctionnera évidemment pas.

9voto

tamouse Points 687

En partant de la réponse de @boulder_ruby, voici ce que je recherche, en supposant que us_eco contient le tableau CSV comme dans mon gist.

CSV.open('outfile.txt','wb', col_sep: "\t") do |csvfile|
  csvfile << us_eco.first.keys
  us_eco.each do |row|
    csvfile << row.values
  end
end

Mise à jour de l'essentiel à https://gist.github.com/tamouse/4647196

2voto

Felix Rabe Points 1256

J'ai moi-même du mal avec ça. Voici mon point de vue :

https://gist.github.com/2639448 :

require 'csv'

class CSV
  def CSV.unparse array
    CSV.generate do |csv|
      array.each { |i| csv << i }
    end
  end
end

CSV.unparse [ %w(your array), %w(goes here) ]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X