如何将哈希保存到CSV中

时间:2011-11-18 14:08:34

标签: ruby csv hash append

我是红宝石的新人,所以请原谅我的顽皮。

我有一个包含两列的CSV。一个用于动物名称,一个用于动物类型。 我有一个散列,其中所有键都是动物名称,值是动物类型。我想在不使用fasterCSV的情况下将哈希写入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) 是否可以以相同的方式回写文件?

8 个答案:

答案 0 :(得分:52)

如果您想要列标题,并且您有多个哈希值:

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上测试)

答案 1 :(得分:40)

试试这个:

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

答案 2 :(得分:23)

我认为原始问题最简单的解决方案是:

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

答案 3 :(得分:9)

CSV可以按任意顺序获取哈希,排除元素,并省略不在<ion-header> <ion-navbar> <ion-title>LED </ion-title> <button ion-button (click)="Command()">{{ComandoTXT}}</button> </ion-navbar> </ion-header> <ion-content padding> <p>LED Messages: ({{myCount}} | {{test}})</p> <hr /> <p *ngFor="let message of messages">{{message}}</p> </ion-content>

中的参数
HEADERS

这使得使用CSV类更加灵活和可读。

答案 4 :(得分:4)

我在这里尝试了解决方案,但结果不正确(错误列中的值),因为我的源代码是一个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

答案 5 :(得分:1)

试试这个:

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

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

答案 6 :(得分:0)

让我们有一个哈希,

      import {Component} from '@angular/core';
      import {NavController} from 'ionic-angular';
      import {UserProvider} from "../../providers/user/user";

      @Component({
        selector: 'page-home',
        templateUrl: 'home.html'
      })
      export class HomePage {

        user: any;

        constructor(
          public navCtrl: NavController,
          private userProvider:UserProvider,
        ) {        


        }

        ngOnInit(){
          this.getUser();
        }



        getUser(){
          this.userProvider.getUser().subscribe(data =>{
            console.log(data);
            this.user = data;
          });
        }


      }

上面的hash_1将密钥作为一些id 1,2,..和值再次与一些密钥一起散列为(:rev,:d_odr,:d_price)。 假设我们想要一个包含标题的CSV文件,

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

然后为hash_1的每个值创建一个新数组并将其插入CSV文件

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

现在您已将design_performance_data_temp.csv文件保存在相应的目录中。 以上代码可以进一步优化。

答案 7 :(得分:0)

[注意] 该线程中的所有答案都假设散列中定义的键的顺序在所有行中都是不变的。

为了防止将某些值分配给 csv 中错误键的问题(我现在面临的问题)(例如:)

hahes = [
    {:cola => "hello", :colb => "bye"},
    {:colb => "bye", :cola => "hello"}
]

使用此线程上大多数答案(包括最佳答案)中的代码生成下表:

cola  | colb
-------------
hello | bye
-------------
bye   | hello

你应该这样做:

require "csv"

csv_rows = [
    {:cola => "hello", :colb => "bye"},
    {:colb => "bye", :cola => "hello"}
]

column_names = csv_rows.first.keys

s=CSV.generate do |csv|
  csv << column_names
  csv_rows.each do |row|
    csv << column_names.map{|column_name| row[column_name]} #To be explicit
  end
end