我有一个相当大的哈希数组(存储在“@hash["response"]["results"])”中,由我的程序以 JSON 格式返回。
我在 Stack Overflow 上看到了几个关于如何将简单哈希转换为 CSV 格式的示例,但是我还没有找到任何使用更大数据集执行此操作的复杂示例。
我想使用哈希键("pluginID"
、"ip"
、"pluginName"
等)作为CSV header 和哈希值("11112"
、"100.100.100.100"
、"此处插件的名称"
等) CSV 行内容。
请注意,“repository”
键本身就是一个哈希值,因此我只想使用名称,而不是 ID 或描述。
非常感谢任何帮助。我已经按照 Ruby CSV 标准库说明使用了一些代码示例,但我什至还没有接近。
@hash = '{
"type": "regular",
"response": {
"Records": "137",
"rRecords": 137,
"startOffset": "0",
"endOffset": "500",
"matchingDataElementCount": "-1",
"results": [
{ "pluginID": "11112",
"ip": "100.100.100.100",
"pluginName": "Name for plugin here",
"firstSeen": "1444208776",
"lastSeen": "1451974232",
"synopsis": "synopsis contents",
"description": "Full description would go here... Full description would go here... Full description would go here... Full description would go here... Full description would go here...",
"solution": "",
"version": "Revision: 1.51",
"pluginText": "output text here",
"dnsName": "name",
"repository": {
"id": "1",
"name": "Name Here As Well",
"description": "Description here also"
},
"pluginInfo": "11112 (0/6) Name for plugin here"
},
{ "pluginID": "11113",
"ip": "100.100.100.100",
"pluginName": "Name for plugin here",
"firstSeen": "1444455329",
"lastSeen": "1451974232",
"synopsis": "Tsynopsis contents",
"description": "Full description would go here... Full description would go here... Full description would go here... Full description would go here... Full description would go here...",
"solution": "",
"version": "Revision: 1.51",
"pluginText": "output text here",
"dnsName": "name here",
"repository": {
"id": "1",
"name": "Name Here As Well",
"description": "Description here also"
},
"pluginInfo": "11112 (0/6) Name for plugin here"
},
{ "pluginID": "11113",
"ip": "100.100.100.100",
"pluginName": "Name for plugin here : Passed",
"firstSeen": "1444455329",
"lastSeen": "1444455329",
"synopsis": "nope, more synopsis data here",
"description": "Uanother different description",
"solution": "",
"version": "Revision: 1.14",
"pluginText": "",
"dnsName": "name here",
"repository": {
"id": "1",
"name": "Name Here As Well",
"description": "Description here also"
},
"pluginInfo": "11114 (0/6) Name for plugin here : Passed"
},
{ "pluginID": "11115",
"ip": "100.100.100.100",
"pluginName": "Name for plugin here",
"firstSeen": "1444455329",
"lastSeen": "1444455329",
"synopsis": "Tsynopsis contents",
"description": "Full description would go here... Full description would go here... Full description would go here... Full description would go here... Full description would go here...",
"solution": "",
"version": "Revision: 1.51",
"pluginText": "output text here",
"dnsName": "",
"repository": {
"id": "1",
"name": "Name Here As Well",
"description": "Description here also"
},
"pluginInfo": "11116 (0/6) Name for plugin here"
}
]
},
"code": 0,
"msg": "",
"msg_det": [],
"time": 1454733549
}'
最佳答案
这很简单。基本上有五个步骤:
- 将 JSON 解析为 Ruby 哈希。
- 从
“results”
数组†中的第一个哈希中获取键名称,并将其作为标题写入 CSV 文件。 迭代
“results”
数组和每个哈希:- 将
“repository”
哈希值替换为其“name”
值。 - 按照与标题相同的顺序提取值并将其写入 CSV 文件。
- 将
代码看起来像这样:
require 'json'
require 'csv'
json = '{
"type": "regular",
"response": {
...
},
...
}'
# Parse the JSON
hash = JSON.parse(json)
# Get the Hash we're interested in
results = hash['response']['results']
# Get the key names to use as headers
headers = results[0].keys
filename = "/path/to/output.csv"
CSV.open(filename, 'w', headers: :first_row) do |csv|
# Write the headers to the CSV
csv << headers
# Iterate over the "results" hashes
results.each do |result|
# Replace the "repository" hash with its "name" value
result['repository'] = result['repository']['name']
# Get the values in the same order as the headers and write them to the CSV
csv << result.values_at(*headers)
end
end
†此代码 (headers = results[0].keys
) 假设第一个 "results"
哈希将包含所有CSV 中您想要的键。如果不是这种情况,您需要:
明确指定 header ,例如:
headers = %w[ pluginId ip pluginName ... ]
循环所有哈希并构建所有键的列表:
headers = results.reduce([]) {|all_keys, result| all_keys | result.keys }
关于Ruby - 如何将大型多维哈希数组转换为 CSV 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35356735/