web-dev-qa-db-fra.com

Comment enregistrer un hachage dans un fichier CSV

Je suis nouveau dans Ruby alors pardonne-moi s'il te plaît.

J'ai un fichier CSV à deux colonnes. Un pour le nom de l'animal et l'autre pour le type d'animal . Je voudrais écrire le hachage au format CSV sans utiliser plus rapide CSV. J'ai pensé à plusieurs idées qui seraient les plus faciles .. voici la mise en page de base.

require "csv"

def write_file
  h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }

  CSV.open("data.csv", "wb") do |csv|
    csv << [???????????]
  end
end

Quand j'ai ouvert le fichier pour le lire, je l'ai ouvert File.open("blabla.csv", headers: true) Serait-il possible d'écrire dans le fichier de la même manière? 

34
TheLegend

Essaye ça:

require 'csv'
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "wb") {|csv| h.to_a.each {|elem| csv << elem} }

Résultera:

1.9.2-p290:~$ cat data.csv 
dog,canine
cat,feline
donkey,asinine
40
Sławosz

Si vous voulez des en-têtes de colonne et que vous avez plusieurs hachages: 

require 'csv'
hashes = [{'a' => 'aaaa', 'b' => 'bbbb'}]
column_names = hashes.first.keys
s=CSV.generate do |csv|
  csv << column_names
  hashes.each do |x|
    csv << x.values
  end
end
File.write('the_file.csv', s)

(testé sur Ruby 1.9.3-p429)

52
Joe Goggins

Je pense que la solution la plus simple à votre question initiale:

def write_file
  h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }

  CSV.open("data.csv", "w", headers: h.keys) do |csv|
    csv << h.values
  end
end

Avec plusieurs hachages qui partagent tous les mêmes clés :

def write_file
  hashes = [ { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' },
             { 'dog' => 'rover', 'cat' => 'kitty', 'donkey' => 'ass' } ]

  CSV.open("data.csv", "w", headers: hashes.first.keys) do |csv|
    hashes.each do |h|
      csv << h.values
    end
  end
end
23
Tom Rossi

CSV peut utiliser un hachage dans n’importe quel ordre, exclure des éléments et omettre un paramètre qui ne figure pas dans la variable HEADERS

require "csv"
HEADERS = [
  'dog',
  'cat',
  'donkey'
]

def write_file

  CSV.open("data.csv", "wb", :headers => HEADERS, :write_headers => true) do |csv|
    csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
    csv << { 'dog' => 'canine'}
    csv << { 'cat' => 'feline', 'dog' => 'canine', 'donkey' => 'asinine' }
    csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine', 'header not provided in the options to #open' => 'not included in output' }
  end
end

write_file # => 
# dog,cat,donkey
# canine,feline,asinine
# canine,,
# canine,feline,asinine
# canine,feline,asinine

Cela rend le travail avec la classe CSV plus flexible et lisible.

6
rudolph9

J'ai essayé les solutions ici, mais j'ai obtenu un résultat incorrect (valeurs dans des colonnes incorrectes) car mon fichier source est un fichier LDIF qui ne contient pas toujours toutes les valeurs d'une clé. J'ai fini par utiliser ce qui suit.

Tout d'abord, lors de la construction du hachage, je me souviens des clés d'un tableau séparé que je complète avec les clés qui n'y sont pas déjà.

# building up the array of hashes
File.read(ARGV[0]).each_line do |lijn|
    case
    when lijn[0..2] == "dn:" # new record
        record = {}
    when lijn.chomp == '' # end record
        if record['telephonenumber'] # valid record ?
            hashes << record
            keys = keys.concat(record.keys).uniq
        end
    when ...
    end
end

La ligne importante ici est keys = keys.concat(record.keys).uniq qui étend le tableau de clés lorsque de nouvelles clés (en-têtes) sont trouvées.

Maintenant le plus important: convertir nos hashes en CSV

CSV.open("export.csv", "w", {headers: keys, col_sep: ";"}) do |row|
  row << keys # add the headers
  hashes.each do |hash|
    row << hash # the whole hash, not just the array of values
  end
end
4
peter

Essaye ça:

require 'csv'
data = { 'one' => '1', 'two' => '2', 'three' => '3' }

CSV.open("data.csv", "a+") do |csv|
        csv << data.keys
        csv << data.values
end
1
Santosh Sharma

Permet d'avoir un hash,

hash_1 = {1=>{:rev=>400, :d_odr=>3}, 2=>{:rev=>4003, :d_price=>300}}

Le hash_1 ci-dessus ayant des clés comme identifiant 1,2, .. et leurs valeurs sont à nouveau des hash avec des clés comme (: rev,: d_odr,: d_price) . Supposons que nous voulions un fichier CSV avec en-têtes,

headers = ['Designer_id','Revenue','Discount_price','Impression','Designer ODR']

Créez ensuite un nouveau tableau pour chaque valeur de hash_1 et insérez-le dans un fichier CSV.

CSV.open("design_performance_data_temp.csv", "w") do |csv|
 csv << headers
 csv_data = []
 result.each do |design_data|
  csv_data << design_data.first
  csv_data << design_data.second[:rev] || 0
  csv_data << design_data.second[:d_price] || 0
  csv_data << design_data.second[:imp] || 0
  csv_data << design_data.second[:d_odr] || 0
  csv << csv_data
  csv_data = []
 end
end

Le fichier design_performance_data_temp.csv est maintenant enregistré dans le répertoire correspondant . Le code ci-dessus peut être optimisé. 

0
shubham mishra