2011-11-18 16 views
29

में कैसे सहेजना है मैं रूबी में नया हूं इसलिए कृपया नोबिशनेस को क्षमा करें।एक हैश को एक CSV

मेरे पास दो कॉलम के साथ एक CSV है। जानवरों के नाम के लिए एक और पशु प्रकार के लिए एक। मेरे पास एक हैश है जिसमें सभी चाबियाँ पशु नाम हैं और मूल्य पशु प्रकार हैं। मैं fastCSV का उपयोग किये बिना सीएसवी को हैश लिखना चाहता हूं। मैंने कई विचारों के बारे में सोचा है जो सबसे आसान होगा .. यहां बुनियादी लेआउट है।

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

बस इतना ही आपको पता है, रूबी 1.9 ने पुराने सीएसवी मॉड्यूल को FasterCSV के साथ बदल दिया है, इसलिए आप वास्तव में FasterCSV का उपयोग कर रहे हैं। चूंकि यह मानक पुस्तकालय का हिस्सा है, इसे 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 up अपने बीमार जवाब देते हैं। :) – 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) 

(रूबी पर परीक्षण किया 1.9.3- पी 429)

+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

मैं समाधान यहाँ की कोशिश की लेकिन एक गलत परिणाम मिला (गलत स्तंभ में मान) के बाद से मेरा स्रोत एक एलडीआईएफ फ़ाइल है जिसमें हमेशा कुंजी के लिए सभी मान नहीं होते हैं। मैं निम्नलिखित का उपयोग कर समाप्त हो गया।

सबसे पहले, हैश का निर्माण करते समय मुझे एक अलग सरणी में चाबियाँ याद होती हैं जिन्हें मैं उन चाबियों के साथ बढ़ाता हूं जो पहले से मौजूद नहीं हैं।

# 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

सीएसवी किसी भी क्रम में एक हैश ले जा सकते हैं, तत्वों को निकालने के लिए, और छोड़ देते हैं एक में नहीं पैरामीटर 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 

यह सीएसवी वर्ग अधिक लचीला और फिर से साथ काम करने में आता है adable।

0

, चलो हम एक हैश है

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

ऊपर hash_1 कुछ आईडी 1,2, के रूप में चाबियाँ होने .. और उन लोगों के लिए मूल्यों को फिर से के रूप में कुछ कुंजियों (साथ हैश रहे हैं: राजस्व,: 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 फ़ाइल हो रही है आपकी संबंधित निर्देशिका में। ऊपर कोड को और अनुकूलित किया जा सकता है।

संबंधित मुद्दे