2015-02-08 38 views
0

我正在寫一個ruby腳本來接受一個CSV輸入文件。我想製作一個漂亮的JSON文件。我覺得我很親密,但我似乎無法達到那裏。我原來的項目是在JS中,但需求已經改變,使其成爲一個Ruby文件。請幫我用我的Ruby腳本(ruby 2.0.0p481)

我輸入文件看起來像這樣

項目ID,描述,價格,成本,價格類型,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的版本我使用的是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>' 
+2

什麼是你的問題?你有錯誤嗎? – spickermann 2015-02-08 20:42:24

+0

將錯誤添加到問題中。我忘了這麼做。對不起 – 2015-02-08 20:46:42

+0

我沒有時間研究這一點,但我懷疑'ARGV [0]'正在評估爲'nil'。在調用「open」之前添加一個'p ARGV [0]'行來確保。 – 2015-02-08 21:09:26

回答

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 
+0

謝謝。輸出必須看起來像我的示例中的那個.ese ese接受文件然後執行其他操作。人的代碼不會改變它的我的節點代碼,需要變成ruby – 2015-02-09 01:41:15

+0

@softwareisfun,你的示例輸出不是json。現在必須讓你走。祝你好運。 – 7stud 2015-02-09 03:37:44