我正在编写一个ruby脚本来接受一个CSV输入文件。我想制作一个漂亮的JSON文件。我觉得我很亲密,但我似乎无法到达那里。我的原始项目是在JS中,但是需求已经改变,使其成为一个Ruby文件。
我的输入文件如下所示
商品ID,描述,价格,成本,price_type,quantity_on_hand,size_1_name,size_1_price,size_2_name,size_2_price,size_3_name,size_3_price
需要注意的一点是,CSV文件中的某些值可能会丢失,因为它不存在。
require 'csv'
require 'json'
def is_int(str)
return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
end
lines = CSV.open(ARGV[0],{:col_sep => ","}).readlines
# remove first entry of the lines array
keys = lines.shift
lines.each do |values|
# convert the line into a hash and transform string into int
#hash=Hash[keys.zip(values.map{|val| is_int(val) ? val.to_i : val}) ]
hash = keys.zip(values.map{ val})
# Write a file with the hash results
File.open("#{hash['NAME']}.json", "w") do |f|
f.write JSON.pretty_generate [hash]
end
end
我想要的输出是
[
{
id: 111010,
description: 'Coffee',
price: 1.25,
cost: 0.80,
price_type: 'system',
quantity_on_hand: 100000,
modifiers: [
{
name: 'Small',
price: -0.25
},{
name: 'Medium',
price: 0.00
},{
name: 'Large',
price: 0.30
}
]
Ruby I使用的版本是2.0.0p481
Error was
usr/lib/ruby/2.0.0/csv.rb:1254:in `initialize': no implicit conversion of nil into String (TypeError)
from /usr/lib/ruby/2.0.0/csv.rb:1254:in `open'
from /usr/lib/ruby/2.0.0/csv.rb:1254:in `open'
from stockimporter.rb:8:in `<main>'
答案 0 :(得分:1)
csv.csv:
id,description,price,cost,price_type,quantity_on_hand,size_1_name,size_1_price,size_2_name,size_2_price,size_3_name,size_3_price
111010,Coffee,1.25,0.80,system,10000,Small,-0.25,Medium,0.00,Large,0.30
111011,Tea,1.00,0.50,system,100,Small,-0.10,Medium,0.00,Large,0.10
111012,MissingInfo,1.00,0.50,,100,,,Medium,,Large,0.10
...
require 'csv'
require 'pp'
require 'json'
csv_options = {
headers: true, #skip first line of csv file
converters: [:numeric] #convert strings that look like integers or floats to integers or floats
}
results = []
CSV.foreach('csv.csv', csv_options) do |row|
record = Hash[row.take(6)]
modifiers = [
{
name: row["size_1_name"],
price: row["size_1_price"]
},
{
name: row["size_2_name"],
price: row["size_2_price"],
},
{
name: row["size_3_name"],
price: row["size_3_price"]
}
]
record['modifiers'] = modifiers
results << record
end
pp results
--output:--
[{"id"=>111010,
"description"=>"Coffee",
"price"=>1.25,
"cost"=>0.8,
"price_type"=>"system",
"quantity_on_hand"=>10000,
"modifiers"=>
[{:name=>"Small", :price=>-0.25},
{:name=>"Medium", :price=>0.0},
{:name=>"Large", :price=>0.3}]},
{"id"=>111011,
"description"=>"Tea",
"price"=>1.0,
"cost"=>0.5,
"price_type"=>"system",
"quantity_on_hand"=>100,
"modifiers"=>
[{:name=>"Small", :price=>-0.1},
{:name=>"Medium", :price=>0.0},
{:name=>"Large", :price=>0.1}]},
{"id"=>111012,
"description"=>"MissingInfo",
"price"=>1.0,
"cost"=>0.5,
"price_type"=>nil,
"quantity_on_hand"=>100,
"modifiers"=>
[{:name=>nil, :price=>nil},
{:name=>"Medium", :price=>nil},
{:name=>"Large", :price=>0.1}]}]
json = JSON.pretty_generate(results)
puts json
--output:--
[
{
"id": 111010,
"description": "Coffee",
"price": 1.25,
"cost": 0.8,
"price_type": "system",
"quantity_on_hand": 10000,
"modifiers": [
{
"name": "Small",
"price": -0.25
},
{
"name": "Medium",
"price": 0.0
},
{
"name": "Large",
"price": 0.3
}
]
},
{
"id": 111011,
"description": "Tea",
"price": 1.0,
"cost": 0.5,
"price_type": "system",
"quantity_on_hand": 100,
"modifiers": [
{
"name": "Small",
"price": -0.1
},
{
"name": "Medium",
"price": 0.0
},
{
"name": "Large",
"price": 0.1
}
]
},
{
"id": 111012,
"description": "MissingInfo",
"price": 1.0,
"cost": 0.5,
"price_type": null,
"quantity_on_hand": 100,
"modifiers": [
{
"name": null,
"price": null
},
{
"name": "Medium",
"price": null
},
{
"name": "Large",
"price": 0.1
}
]
}
]
你也可以这样做:
CSV.foreach('csv.csv', csv_options) do |row|
record = Hash[row.take(6)]
price_adjustments = row.drop(6)
# [["size_1_name", "Small"], ["size_1_price", -0.25]]
# |---------------------------------------------------|
# ^
# |
modifiers = price_adjustments.each_slice(2).map do |size_price|
size_price.first[0] = 'name'
size_price.last[0] = 'price'
Hash[size_price]
end
p modifiers #e.g. [{"name"=>"Small", "price"=>-0.25}, {"name"=>"Medium", "price"=>0.0}, {"name"=>"Large", "price"=>0.3}]
record['modifiers'] = modifiers
results << record
end
pp results