1

I have a Ruby array of students. Student class has attributes id, name and age.

students = [ 
             {id:"id1",name:"name1",age:"age1"}, 
             {id:"id2",name:"name2",age:"age2"},
             {id:"id3",name:"name3",age:"age3"}
           ]

I want to create a JSON key value object from this array as follows.

json_object = {id1:name1, id2:name2, id3:name3}

3 Answers 3

4
input = [ {id:"id1",name:"name1",age:"age1"},
          {id:"id2",name:"name2",age:"age2"},
          {id:"id3",name:"name3",age:"age3"}]

require 'json'
JSON.dump(input.map { |hash| [hash[:id], hash[:name]] }.to_h)
#⇒ '{"id1":"name1","id2":"name2","id3":"name3"}'
Sign up to request clarification or add additional context in comments.

5 Comments

Wow. I had no idea that you could use .to_h like that on an array of arrays. Super nice! Would you please comment on JSON.dump vs. .to_json?
@jvillian sure. I don’t trust monkeypatches. to_json might be explicitly blocked/overwritten/whatever.
@mudasobwa Is this monkeypatch in Ruby context? Or does this apply to Rails (Hash#to_json) as well?
@jemonsanto of course there is to_json in the ruby core. The thing is Rails or whoever do extensively overwrite/monkeypatch the default Ruby implementation, and what I need is an old good one from ruby core.
@mudasobwa Neato! Thanks for the explanation, didn't see the alternative way (doh). Just skimmed on it.
2

Give this a go:

students = [ 
             {id:"id1",name:"name1",age:"age1"}, 
             {id:"id2",name:"name2",age:"age2"},
             {id:"id3",name:"name3",age:"age3"}
           ]

json_object = students.each_with_object({}) do |hsh, returning|
  returning[hsh[:id]] = hsh[:name]
end.to_json

In console:

puts json_object
 => {"id1":"name1","id2":"name2","id3":"name3"}

Comments

2

Your data is all identical, but if you wanted to generate a hash that took the value of students[n][:id] as keys and students[n][:name] as values you could do this:

student_ids_to_names = students.each_with_object({}) do |student, memo|
  memo[student[:id]] = student[:name]
end

For your data, you'd end up with only one entry as the students are identical: { "id1" => "name1" }. If the data were different each key would be unique on :id.

Once you have a hash, you can call json_object = students_ids_to_names.to_json to get a JSON string.

1 Comment

Prefer each_with_object over inject for mutable accumulators.

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.