【问题标题】:Convert CSV to a nested Ruby hash/JSON将 CSV 转换为嵌套的 Ruby 哈希/JSON
【发布时间】:2016-09-14 18:30:18
【问题描述】:

我是 ruby​​ 和 json 的新手,所以可能以错误的方式处理这个问题。

我想获取一个以管道分隔格式的清单并将其转换为 json。

我已经尝试过这里的示例Convert csv to json in ruby

但是我有点纠结于逻辑,因为数据采用平面格式,将转换为嵌套列中的值匹配,例如 csv 文件将如下所示:-

id|shelf|package|price
cupboarda|shelf1|can1|10
cupboarda|shelf1|box1|20
cupboarda|shelf2|can1|10
cupboarda|shelf2|box1|20
cupboarda|shelf3|can1|30

我正在尝试将其转换为 json,例如:-

{
  "id": "cupboarda",
  "shelf": {
    "shelf1": {
      "package": {
        "can1": {
          "price": "10"
        },
        "box1": {
          "price": "20"
        }
      }
    },
    "shelf2": {
      "package": {
        "can1": {
          "price": "10"
        },
        "box1": {
          "price": "20"
        }
      }
    },
    "shelf3": {
      "package": {
        "can1": {
          "price": "30"
        }
      }
    }
  }
}

我认为我在链接中的示例上走在了正确的轨道上,但我对嵌套它的方式有点卡住了。

这是我尝试将所有内容放入一种块中的一种方法,因此我可以找出一些逻辑,将字段提取到嵌套 JSON 或嵌套哈希中,然后我可以将其格式化为 json 或其他东西否则。

require 'csv'
csv_data = CSV.read 'data.csv', :col_sep => "|"
headers = csv_data.shift.map {|i| i.to_s }
string_data = csv_data.map {|row| row.map {|cell| cell.to_s } }
array_of_hashes = string_data.map {|row| Hash[*headers.zip(row).flatten] }

puts "Array"
p array_of_hashes

让我束手无策的是试图弄清楚如何使用 id 中的值并开始分割和嵌套数据。 刚从 Ruby 开始,所以逻辑部分是我的砖墙,上面的代码是我在其他地方找到的,我认为它给了我想要的东西,但可能不是最好的方法。

更新>

我仍然试图围绕这个逻辑来思考,但到目前为止我已经走了多远:-

require 'csv'
require 'json'

csv_data = CSV.read 'inv.csv', :col_sep => "|"
headers = csv_data.shift.map {|i| i.to_s }
string_data = csv_data.map {|row| row.map {|cell| cell.to_s } }
array_of_hashes = string_data.map {|row| Hash[*headers.zip(row).flatten] }

summary = {}
array_of_hashes.each do |rec|
  ida, shelfa, packagea, pricea = rec.values_at('id','shelf','package','price')
  ((summary[ida] ||= {})[shelfa] ||= {})[packagea] ||= 0
  summary[ida][shelfa][packagea] = pricea
end
puts summary.to_json
puts summary

如果我将数据放入名为 inv.csv 的文件中,会产生接近我想要的结果。

我得到这个输出

{"cupboarda":{"shelf1":{"can1":"10","box1":"20"},"shelf2":{"can1":"10","box1":"20"},"shelf3":{"can1":"30"}}}
{"cupboarda"=>{"shelf1"=>{"can1"=>"10", "box1"=>"20"}, "shelf2"=>{"can1"=>"10", "box1"=>"20"}, "shelf3"=>{"can1"=>"30"}}}

我只需要弄清楚我可以让谁紧凑,例如:-

{"cupboard":"cupboarda","shelf":{"shelf1":{"package":{"can1":{"price":"10"},"box1":{"price":"20"}}},"shelf2":{"package":{"can1":{"price":"10"},"box1":{"price":"20"}}},"shelf3":{"package":{"can1":{"price":"30"}}}}}

【问题讨论】:

  • 请展示你的努力。
  • 你到底尝试了什么?请发布您的实际代码。
  • 首先我尝试了链接中的示例。然后我尝试这个例子把它转换成一个哈希数组require 'csv' csv_data = CSV.read 'data.csv', :col_sep => "|" headers = csv_data.shift.map {|i| i.to_s } string_data = csv_data.map {|row| row.map {|cell| cell.to_s } } array_of_hashes = string_data.map {|row| Hash[*headers.zip(row).flatten] } puts "Array" p array_of_hashes然后我计划提取一些uniq值来执行一些搜索以产生嵌套输出cupboard = array_of_hashes.map { |h| h["cupboard"] }.uniq
  • @Steve 正如您所看到的,代码在 cmets 中的可读性不是很高。可以,甚至更喜欢将您尝试过的代码放在问题本身中。您可以在您的问题上单击“编辑”并添加它,说明这是您迄今为止尝试过的。

标签: ruby json csv


【解决方案1】:

您使用什么语言?

对于 javascript,请在​​ Google 中查找“jsfiddle csv json”和 c# take a look at this question。在我的 c# 项目中,我使用了NewtonSoft's brilliant JSON 框架。

【讨论】:

  • 你读过问题的标题吗? 将 CSV 转换为嵌套的 Ruby 哈希/JSON,此问题也标记为 ruby​​。
  • 好的,为什么我的回答被否决了?他没有具体说明他使用的语言,我给了他一些一般性的指示。如果您愿意阅读或点击链接......
  • 尝试在 ruby​​ 中实现
猜你喜欢
  • 2013-11-13
  • 1970-01-01
  • 2020-12-22
  • 2019-08-01
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
相关资源
最近更新 更多