luzny
luzny

Reputation: 2400

How to convert flat hash into nested after conditional key?

I'm trying to convert xml into json structure. I got all rows, extract first as header and zip it with all next rows, but I have to nest keys after word attribute, how to do it?

current steps:

vars:

header = ["id",
 "groupName",
 "words",
 "Unit",
 "Name",
 "Image"]

rows = [["1",
  "gr 1",
  nil,
  "1",
  "Test",
  "test.png"],
 ["1",
  "gr 1",
  nil,
  "23",
  "Taefawe",
  "adf.png"]]

current output =>

[{"id"=>"1",
  "groupName"=>"Unit 1",
  "words"=>nil,
  "Unit"=>"1",
  "Name"=>"Test",
  "Image"=>"test.png"},
 {"id"=>"1",
  "groupName"=>"gr 1",
  "words"=>nil,
  "Unit"=>"23",
  "Name"=>"Taefawe",
  "Image"=>"adf.png"}]

desired:

[{"id"=>"1",
  "groupName"=>"Unit 1",
  "words"=>{
    "Unit"=>"1",
    "Name"=>"Test",
    "Image"=>"test.png"
  }
 },
 {"id"=>"1",
  "groupName"=>"gr 1",
  "words"=> {
    "Unit"=>"23",
    "Name"=>"Taefawe",
    "Image"=>"adf.png"
  }}]

current code:

rows = doc.sheets.first.rows
header = rows.shift

out = []
rows.each do |row|
  out << Hash[header.zip(row.map{|val| val})]
end

Upvotes: 0

Views: 162

Answers (2)

Sid
Sid

Reputation: 2943

If you are getting it back as true xml you should be able to just use:

Hash.from_xml(doc.sheets)

Upvotes: 2

Saurabh
Saurabh

Reputation: 73649

In case your headers is always constant, the best way it seemed to me is:

rows.inject([]) do |res, row|
  res << {"id" => row[0],
          "groupName" => row[1],
          "words" => {
                        "Unit" => row[3],
                        "Name"  => row[4],
                        "Image" => row[5]} 
         }
end

or you can replace the key constants in the hash with header[index] as well.

Upvotes: 1

Related Questions