2011-11-18 90 views
29

我是Ruby中的新成員,請原諒Noobishness。如何將散列保存爲CSV

我有兩列的CSV。一個用於動物名稱,一個用於動物類型。 我有一個哈希,所有的鍵是動物名稱和值是動物類型。我想在不使用更快的CSV的情況下將散列寫入CSV。我想到了幾個最簡單的想法..這裏是基本的佈局。

require "csv" 

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

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

當我打開文件,從中讀取我打開了它File.open("blabla.csv", headers: true) 是否可以寫回文件的方式?

+0

感謝您對我的問題進行投票。 :) – TheLegend

+3

大家知道,Ruby 1.9用FasterCSV取代了舊的CSV模塊,所以你實際上使用了FasterCSV。因爲它是標準庫的一部分,所以它被稱爲CSV而不是FasterCSV。 –

回答

39

試試這個:

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

會導致:

1.9.2-p290:~$ cat data.csv 
dog,canine 
cat,feline 
donkey,asinine 
+0

是的,這是主意。將其轉換回陣列..非常酷的感謝!並使用一個塊做它加5分!舉手擊掌! :) – TheLegend

+3

當我lvl起來時,你的答案投給你。 :) – TheLegend

49

如果你想列標題,您有多個散列:

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) 

(關於Ruby測試1.9.3- p429)

+0

爲了保存列標題,其他答案都不起作用。此答案正常工作 –

+0

如果您不想實際輸出到磁盤上的文件,'CSV.generate'非常方便。 – Beejamin

21

我覺得最簡單的解決方案,你原來的問題:

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 

使用多個哈希所有共享相同的密鑰

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 
1

我試過的解決方案在這裏,但有一個不正確的結果(在錯誤的列值),因爲我的源代碼是一個LDIF文件,它並不總是具有某個鍵的所有值。我結束了使用以下。

首先,當建立哈希值時,我記得單獨數組中的密鑰,我使用不是已經存在的密鑰進行擴展。

# 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 

重要這裏線是keys = keys.concat(record.keys).uniq其中,當新的密鑰(標題)被發現延伸鍵陣列。

現在最重要的是:將我們的哈希值到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 
1

試試這個:

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

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

CSV可以利用哈希以任意順序,排除元素,而忽略在PARAMS不在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 

這使得與CSV類更加靈活和重新工作adable。

0

讓我們有一個哈希值,

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

具有鍵作爲一些ID 1,2,上述hash_1 ..和值的那些被再次與一些鍵用作(散列:REV,:d_odr,: d_price)。 假設我們希望有一個與CSV文件頭,

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

然後,讓一個新的陣列hash_1的每個值和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 

現在你有保存design_performance_data_temp.csv文件在你的相應目錄中。以上代碼可以進一步優化。