回答
嘗試是這樣的:
require 'csv'
require 'json'
csv_string = CSV.generate do |csv|
JSON.parse(File.open("foo.json").read).each do |hash|
csv << hash.values
end
end
puts csv_string
不錯,簡單。 請記住,這不會考慮嵌套並假定列表中的所有對象都是相同的。 – SirLenz0rlot
要實際寫入文件...
require 'csv'
require 'json'
CSV.open("your_csv.csv", "w") do |csv| #open new file for write
JSON.parse(File.open("your_json.json").read).each do |hash| #open json to parse
csv << hash.values #write value to file
end
end
我覺得easies方式到JSON轉換爲CSV紅寶石中使用json2csv紅寶石的寶石。 PS:我可能會因爲我的作者而有偏見。
運行命令
json2csv convert data/sample.json
輸入文件
在這種特定情況下它會轉換以下JSON:
cat data/sample.json
{
"12345": {
"Firstname": "Joe",
"Lastname": "Doe",
"Address": {
"Street": "#2140 Taylor Street, 94133",
"City": "San Francisco",
"Details": {
"note": "Pool available"
}
}
},
"45678": {
"Firstname": "Jack",
"Lastname": "Plumber",
"Address": {
"Street": "#111 Sutter St, 94104",
"City": "San Francisco",
"Details": {
"note": "Korean Deli near to main entrance"
}
}
}
輸出
cat data/sample.json.csv
id,Firstname,Lastname,Address.Street,Address.City,Address.Details.note
12345,Joe,Doe,"#2140 Taylor Street, 94133",San Francisco,Pool available
45678,Jack,Plumber,"#111 Sutter St, 94104",San Francisco,Korean Deli near to main entrance
基於@Alex's answer但加入CSV頭和示例測試。
# utils.rb
require "csv"
module Utils
def self.array_of_hashes_to_csv(array_of_hashes)
CSV.generate do |csv|
csv << array_of_hashes.first.keys
array_of_hashes.each { |hash| csv << hash.values }
end
end
end
# utils_test.rb
class UtilsTest < MiniTest::Unit::TestCase
def test_array_of_hashes_to_csv
array_of_hashes = [
{ :key1 => "value1", :key2 => "value2" },
{ :key1 => "value3", :key2 => "value4" }
]
expected_result = "key1,key2\nvalue1,value2\nvalue3,value4\n"
assert_equal(expected_result, Utils.array_of_hashes_to_csv(array_of_hashes))
end
end
將json轉換爲csv的Ruby代碼。
通過將數組轉換爲雙引號字符串來處理數組。
#json-to-csv.rb
require 'json'
require 'csv'
file = File.read('./input.json')
hash = JSON.parse(file)
CSV.open('./output.csv', 'w') do |csv|
headers = hash.first.keys
csv << headers
hash.each do |item|
values = item.values
printable_values = Array.new
values.each do |value|
printable_values << value.to_s.gsub(/\[|\]/,'').gsub(/"/,'\'')
end
csv << printable_values
end
end
編輯:
下面描述此功能是現在可作爲gem。與gem install json_converter
安裝完成後,下面的片段可以用來從有效的JSON字符串或對象生成CSV:
require 'json_converter'
json_converter= JsonConverter.new
# Assume json is a valid JSON string or object
csv = json_converter.generate_csv json
原來的答案:
如果你的JSON數據相對簡單(沒有嵌套或數組),Alex的答案可能是處理這個問題最簡單的方法。
但是,如果你做需要考慮數組和嵌套對象,我試圖將這樣一個轉換器的web version端口轉移到紅寶石。它可以發現here。處理數據實際重組的方法是array_from
和flatten
。
array_from
方法嘗試識別給定數據集的「行」數據的外觀。這並不完美,您可能想要針對不同的數據集調整此部分。
# Attempt to identify what a "row" should look like
def array_from(json)
queue, next_item = [], json
while !next_item.nil?
return next_item if next_item.is_a? Array
if next_item.is_a? Hash
next_item.each do |k, v|
queue.push next_item[k]
end
end
next_item = queue.shift
end
return [json]
end
的flatten
方法在JSON(多個)對象遞歸迭代,併產生表示標題和值的對象。如果對象是嵌套的,則其列的標題將以它的父鍵作爲前綴,由/
字符分隔。
# The path argument is used to construct header columns for nested elements
def flatten(object, path='')
scalars = [String, Integer, Fixnum, FalseClass, TrueClass]
columns = {}
if [Hash, Array].include? object.class
object.each do |k, v|
new_columns = flatten(v, "#{path}#{k}/") if object.class == Hash
new_columns = flatten(k, "#{path}#{k}/") if object.class == Array
columns = columns.merge new_columns
end
return columns
elsif scalars.include? object.class
# Remove trailing slash from path
end_path = path[0, path.length - 1]
columns[end_path] = object
return columns
else
return {}
end
end
如果在原來的JSON任何null
的價值,您需要在嘗試轉換之前將這些轉化爲比nil
其他的東西 - 你一般會擁有不平行,如果你不這樣做。該nils_to_strings
方法處理的是:
# Recursively convert all nil values of a hash to empty strings
def nils_to_strings(hash)
hash.each_with_object({}) do |(k,v), object|
case v
when Hash
object[k] = nils_to_strings v
when nil
object[k] = ''
else
object[k] = v
end
end
end
這裏是如何做到這一點用一個簡單的例子:
json = JSON.parse(File.open('in.json').read)
in_array = array_from json
in_array.map! { |x| nils_to_strings x }
out_array = []
in_array.each do |row|
out_array[out_array.length] = flatten row
end
headers_written = false
CSV.open('out.csv', 'w') do |csv|
out_array.each do |row|
csv << row.keys && headers_written = true if headers_written === false
csv << row.values
end
end
最後,這裏的一些例子輸入/輸出:
輸入:
{
"Forms": [
{
"Form": {
"id": "x",
"version_id": "x",
"name": "x",
"category": "",
"subcategory": null,
"is_template": null,
"moderation_status": "x",
"display_status": "x",
"use_ssl": "x",
"modified": "x",
"Aggregate_metadata": {
"id": "x",
"response_count": "x",
"submitted_count": "x",
"saved_count": "x",
"unread_count": "x",
"dropout_rate": "x",
"average_completion_time": null,
"is_uptodate": "x"
}
},
"User": {
"username": "[email protected]"
}
},
{
"Form": {
"id": "x",
"version_id": "x",
"name": "x",
"category": "",
"subcategory": null,
"is_template": null,
"moderation_status": "x",
"display_status": "x",
"use_ssl": "x",
"modified": "x",
"Aggregate_metadata": {
"id": "x",
"response_count": "x",
"submitted_count": "x",
"saved_count": "x",
"unread_count": "x",
"dropout_rate": "x",
"average_completion_time": null,
"is_uptodate": "x"
}
},
"User": {
"username": "[email protected]"
}
}
]
}
輸出:
Form/id,Form/version_id,Form/name,Form/category,Form/subcategory,Form/is_template,Form/moderation_status,Form/display_status,Form/use_ssl,Form/modified,Form/Aggregate_metadata/id,Form/Aggregate_metadata/response_count,Form/Aggregate_metadata/submitted_count,Form/Aggregate_metadata/saved_count,Form/Aggregate_metadata/unread_count,Form/Aggregate_metadata/dropout_rate,Form/Aggregate_metadata/average_completion_time,Form/Aggregate_metadata/is_uptodate,User/username
x,x,x,"","","",x,x,x,x,x,x,x,x,x,x,"",x,[email protected]
x,x,x,"","","",x,x,x,x,x,x,x,x,x,x,"",x,[email protected]
這是句柄頭&嵌套的json。
require 'csv'
require 'json'
@headers = []
file = File.open('file.json')
JSON.parse(file.read).each do |h|
h.keys.each do |key|
@headers << key
end
end
uniq_headers = @headers.uniq
file = File.open('file.json')
finalrow = []
JSON.parse(file.read).each do |h|
final = {}
@headers.each do |key2|
final[key2] = h[key2]
end
finalrow << final
end
CSV.open('output.csv' , 'w') do |csv|
csv << uniq_headers
finalrow.each do |deal|
csv << deal.values
end
end
- 1. 在C++中將JSON轉換爲CSV
- 2. 將JSON流轉換爲CSV
- 3. 將CSV轉換爲JSON
- 4. 將JSON轉換爲CSV
- 5. 將JSON轉換爲CSV
- 6. 將JSON轉換爲CSV
- 7. 將Azure中的JSON轉換爲CSV
- 8. 將JSON轉換爲Ruby中的hashmap
- 9. 將bson轉換爲json(然後轉換爲csv或在Stata中加載json)
- 10. Ruby/CSV - 將Dos轉換爲Unix
- 11. Ruby Nokogiri將KML轉換爲CSV
- 12. 用於將CSV轉換爲JSON的Ruby腳本
- 13. 使用PowerShell將CSV轉換爲JSON和JSON爲CSV
- 14. 將csv轉換爲JSON樹結構?
- 15. 使用PHP將CSV轉換爲JSON
- 16. 使用json2csv.py將JSON轉換爲CSV
- 17. 使用python將csv轉換爲json
- 18. 使用熊貓將JSON轉換爲CSV
- 19. 使用jq將JSON轉換爲CSV
- 20. Python - 將csv文件轉換爲JSON
- 21. 如何將CSV轉換爲JSON?
- 22. 使用PHP將CSV轉換爲JSON?
- 23. 如何將JSON轉換爲CSV?
- 24. PHP庫將JSON轉換爲CSV?
- 25. 尋找將JSON轉換爲CSV的DSL
- 26. 將CSV轉換爲嵌套JSON
- 27. 將JSON解析數組轉換爲CSV
- 28. 將json對象轉換爲csv輸出
- 29. 如何將json轉換爲csv
- 30. 將CSV轉換爲JSON解決方案
看看這個:http://stackoverflow.com/questions/5357711/csv-to-json-ruby-script – WarHog
你有JSON數據的例子嗎? JSON本身可能是多維的,而csv是二維的。 – mliebelt