1

CSV

id,modifier1_name,modifier2_price,modifier2_name,modifier2_price,modifier2_status
1,'Small',10,'Large',20,'YYY'
2,'Small',20,'Large',30,'YYY'

JSON

[
{
 id: 1,
 modifier: [
   {name: 'Small', price: 10},
   {name: 'Large', price: 20, status: 'YYY'}]
},
{
 id: 2,
 modifier: [
   {name: 'Small', price: 20},
   {name: 'Large', price: 30, status: 'YYY'}],
}
]

How to convert CSV to Json in this case when modifiers can be different ?

krunal shah
  • 16,089
  • 25
  • 97
  • 143

2 Answers2

4
require 'csv'
require 'json'

CSV.open('filename.csv', :headers => true).map { |x| x.to_h }.to_json
bjhaid
  • 9,592
  • 2
  • 37
  • 47
  • The way you mentioned It will not generate array of modifiers. I know how to simply convert csv to json. – krunal shah Apr 20 '14 at 19:54
  • @krunalshah you have modifier occurring more than once in your `JSON` object which I doubt is possible, if you correct that then I can update my answer – bjhaid Apr 20 '14 at 20:02
  • 1
    in Ruby 2.2.0 the final `.to_json` is not necessary: `myjson = CSV.open(filename, :headers => true).map { |x| x.to_h }` works fine. if you add the `.to_json` you will get broken strings – mga May 22 '15 at 16:33
4

You will need to map the modifiers yourself, as there is no built-in method to map hash values into an array from your logic:

JSON.pretty_generate(CSV.open('filename.csv', headers: true).map do |row|
  modifier = {}
  row.each do |k, v|
    if k =~ /modifier(.)_(.*)$/
      (modifier[$1] ||= {})[$2] = v
    end
  end
  { id: row['id'],
    modifier: modifier.sort_by { |k, v| k }.map {|k, v| v }
  }
end)

For the file*

id,modifier1_name,modifier1_price,modifier2_name,modifier2_price,modifier2_status
1,Small,10,Large,20,YYY
2,Small,20,Large,30,YYY

*I made some changes to the file you show, since it will not give you the required result - you state modifier2_price twice, for example

You will get:

[
  {
    "id": "1",
    "modifier": [
      {
        "name": "Small",
        "price": "10"
      },
      {

        "name": "Large",
        "price": "20",
        "status": "YYY"
      }
    ]
  },
  {
    "id": "2",
    "modifier": [
      {
        "name": "Small",
        "price": "20"
      },
      {
        "name": "Large",
        "price": "30",
        "status": "YYY"
      }
    ]
  }
]
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93