6

I have a json file that I need to access and modify with a ruby script. I know how to open a json, how to write a new one, but can I modify an existing one?

I have searched for it a bit, but I have not found anything helpfull yet.. Only results treats on different programming languages ..

exemple : I want to modify a wrong data, like below, Anna's last name.

employee.json

{"employees":[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}

=>

{"employees":[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"David"},
    {"firstName":"Peter", "lastName":"Jones"}
]}

Thanks in advance,

4
  • Read the json file into a ruby structure (hash, in this case). Modify the ruby structure. Write it out to the file. PROFIT. Commented Jul 1, 2015 at 8:12
  • Yeah, but does it still work for a large file? (~15k lines) Commented Jul 1, 2015 at 9:14
  • Why wouldn't it work? Commented Jul 1, 2015 at 9:22
  • The point is, I was afraid that work on a large file would require a lot of capacity. But, as shivam explained clearly, that is still the best way to go when you look at the complexity. Whatever, i'll go for that way ! Thanks Commented Jul 1, 2015 at 9:35

2 Answers 2

11

Convert json to hash, edit hash, convert back to json:

require 'json'

a = '{"employees":[
      {"firstName":"John", "lastName":"Doe"},
      {"firstName":"Anna", "lastName":"Smith"},
      {"firstName":"Peter", "lastName":"Jones"}
    ]}'

# Converting JSON to Hash
hash = JSON.parse a
# => {"employees"=>[{"firstName"=>"John", "lastName"=>"Doe"}, {"firstName"=>"Anna", "lastName"=>"Smith"}, {"firstName"=>"Peter", "lastName"=>"Jones"}]} 

# Modifying Hash as required
hash["employees"][1]["lastName"]  = "David"

# Modified Hash
hash
# => {"employees"=>[{"firstName"=>"John", "lastName"=>"Doe"}, {"firstName"=>"Anna", "lastName"=>"David"}, {"firstName"=>"Peter", "lastName"=>"Jones"}]}


# Converting Hash back to JSON
hash.to_json
#  "{\"employees\":[{\"firstName\":\"John\",\"lastName\":\"Doe\"}, {\"firstName\":\"Anna\",\"lastName\":\"David\"}, {\"firstName\":\"Peter\",\"lastName\":\"Jones\"}]}"

I have directly modified the hash as I can see the exact index and iterating through Hash was not the question. But in real world example you may want to go through the Hash to look for key and then modify it, instead of doing to directly as in above example.

You can use pretty_generate to pretty print your json. Here:

hash
# => {"employees"=>[{"firstName"=>"John", "lastName"=>"Doe"}, {"firstName"=>"Anna", "lastName"=>"David"}, {"firstName"=>"Peter", "lastName"=>"Jones"}]}

puts JSON.pretty_generate hash
#{
#  "employees": [
#    {
#      "firstName": "John",
#      "lastName": "Doe"
#    },
#    {
#      "firstName": "Anna",
#      "lastName": "David"
#    },
#    {
#      "firstName": "Peter",
#      "lastName": "Jones"
#    }
#  ]
#}
Sign up to request clarification or add additional context in comments.

2 Comments

As simple as that... Thank you ! But , does it still be efficiency with large json file? (~ 15k lines)
operation on Hash is O(1). Which is magnitudes more efficient than alternate options like reading line by line and editing the file.
1

jsonpath gem can do it out of the box

JsonPath.for('{"candy":"lollipop"}').gsub('$..candy') {|v| "big turks" }.to_hash

in your case something like

require 'jsonpath'

a = '{"employees":[
      {"firstName":"John", "lastName":"Doe"},
      {"firstName":"Anna", "lastName":"Smith"},
      {"firstName":"Peter", "lastName":"Jones"}
    ]}'
JsonPath.for(a).gsub('$.employees[1].lastName') {|v| "David" }.to_hash

will do the trick

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.