How to save a hash into a CSV

前端 未结 7 1552
名媛妹妹
名媛妹妹 2020-12-08 04:26

I am new in ruby so please forgive the noobishness.

I have a CSV with two columns. One for animal name and one for animal type. I have a hash with all the keys being

相关标签:
7条回答
  • 2020-12-08 04:41

    If you want column headers and you have multiple hashes:

    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)
    

    (tested on Ruby 1.9.3-p429)

    0 讨论(0)
  • 2020-12-08 04:42

    I tried the solutions here but got an incorrect result (values in wrong columns) since my source is a LDIF file that not always has all the values for a key. I ended up using the following.

    First, when building up the hash I remember the keys in a separate array which I extend with the keys that are not allready there.

    # 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
    

    The important line here is keys = keys.concat(record.keys).uniq which extends the array of keys when new keys (headers) are found.

    Now the most important: converting our hashes to a 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
    
    0 讨论(0)
  • 2020-12-08 04:42

    Try this:

    require 'csv'
    data = { 'one' => '1', 'two' => '2', 'three' => '3' }
    
    CSV.open("data.csv", "a+") do |csv|
            csv << data.keys
            csv << data.values
    end
    
    0 讨论(0)
  • 2020-12-08 04:54

    CSV can take a hash in any order, exclude elements, and omit a params not in the 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
    

    This makes working with the CSV class more flexible and readable.

    0 讨论(0)
  • 2020-12-08 04:57

    I think the simplest solution to your original question:

    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
    

    With multiple hashes that all share the same keys:

    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
    
    0 讨论(0)
  • 2020-12-08 05:00

    Lets we have a hash,

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

    The above hash_1 having keys as some id 1,2,.. and values to those are again hash with some keys as (:rev, :d_odr, :d_price). Suppose we want a CSV file with headers,

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

    Then make a new array for each value of hash_1 and insert it in CSV file,

    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
    

    Now you are having design_performance_data_temp.csv file saved in your corresponding directory. Above code can further be optimized.

    0 讨论(0)
提交回复
热议问题