如何从ruby中的hash获取正确的csv格式

时间:2015-07-01 13:30:35

标签: ruby csv hash

哈希到csv

哈希:

{
"employee" => [
  {
    "name" => "Claude",
    "lastname"=> "David",
    "profile" => [
       "age" => "43",
       "jobs" => [
         {
           "name" => "Ingeneer",
           "year" => "5"
         }
       ],
       "graduate" => [
          {
             "place" => "Oxford",
             "year" => "1990"
          },
       ],
       "kids" => [
         {
           "name" => "Viktor",
           "age" => "18",
         }
    ]
  }
}]

这是我要处理的哈希的一个例子。因此,正如您所看到的,其中有许多级别的数组。

我的问题是,如何将其正确放入CSV文件?

我试过了:

column_names = hash['employee'].first.keys
s=CSV.generate do |csv|
   csv << column_names
   hash['scrap'].each do |x|
     csv << x.values
   end
end
File.write('myCSV.csv', s)

但我只能获得namelastnameprofile作为键,当我抓住所有这些时(agejobs,{{1 }},nameyeargraduate ...)。

此外,我如何将每个案例的一个值关联起来? 因为我实际上拥有单独使用单元格的所有place。我错过了哪些参数?

Ps:这可能是this post

的以下内容

3 个答案:

答案 0 :(得分:1)

如果您想将哈希值转换为CSV文件或记录,则需要获得“平坦”信息。表示您的键和值。如下所示:

h = {
 a: 1,
 b: {
  c: 3,
  d: 4,
  e: {
    f: 5
  },
  g: 6
 } 
}

def flat_keys(h)
  h.keys.reject{|k| h[k].is_a?(Hash)} + h.values.select{|v| v.is_a?(Hash)}.flat_map{|v| flat_keys(v)}
end

flat_keys(h)
# [:a, :c, :d, :g, :f]

def flat_values(h)
  h.values.flat_map{|v| v.is_a?(Hash) ? flat_values(v) : v}
end

flat_values(h)
# [1, 3, 4, 5, 6]

然后您可以应用它来创建CSV输出。

答案 1 :(得分:1)

有效的CSV输出具有固定数量的列,您的散列具有可变数量的值。密钥jobsgraduatekids都可以包含多个值。

如果您的唯一目标是创建一个可以在Excel中读取的CSV输出,您可以枚举您的Hash,获取每个键的最大键/值对数,总计它,然后写入您的CSV输出,填充带有“”的空白值。

Stack Overflow上有很多例子,首先搜索“深度哈希”。

您提供的每个哈希值都会产生不同数量的列。

如果你问我这太过分了。 如果您只想提供可读的结果,那么您最好和最简单的选择是将Hash转换为为可读性而创建的YAML:

require 'yaml'
hash = {.....}
puts hash.to_yaml

employee:
- name: Claude
  lastname: David
  profile:
  - age: '43'
    jobs:
    - name: Ingeneer
      year: '5'
    graduate:
    - place: Oxford
      year: '1990'
    kids:
    - name: Viktor
      age: '18'

答案 2 :(得分:0)

这取决于数据库中这些字段的表示方式。

例如,您的jobs的哈希值为name,而kids的哈希值为name,因此您不能#39;平坦化&#39;它们,因为键必须是唯一的。

jobs可能是另一个模型(数据库表),因此您可能必须(根据数据库)单独编写它,包括相关对象的id等内容。

你确定你没有超过你的头脑吗?从您的上一个问题来看,并且因为您似乎将csv作为简单的键值对而忽略了所有数据库表示和关系。