1

I have an array of hashes that looks like this:

   array= [
      {
        "id"=> 101,
        "first_name"=> "xxx",
        "last_name"=> "G",
        "email"=> "[email protected]",
        "phone_number"=> "555-555-5555"
      },
      {
        "id"=> 102,
        "first_name"=> "Jen",
        "last_name"=> "P",
        "email"=> "[email protected]",
        "phone_number"=> "555-555-5555"
      }
    ]

I want to convert it to a hash that looks like this:

   array = {
          "101"=> 
          {
            "first_name"=> "xxx",
            "last_name"=> "G",
            "email"=> "[email protected]",
            "phone_number"=> "555-555-5555"
          },
          "102"=>
          {
            "first_name"=> "Jen",
            "last_name"=> "P",
            "email"=> "[email protected]",
            "phone_number"=> "555-555-5555"
          }
       }

I have tried this but it does not work:

    array.each do |a|
      a.map{|x| x[:id]}
    end

How can I do this in Ruby? I am looking at the map function, but not sure how to implement it in this case. Please help!

4
  • anyway, your array of hashes have the wrong syntax, it's not a Ruby hash, it's looks like javascript json Commented Jul 13, 2015 at 7:45
  • @Зелёный Okay thanks for pointing out. I am using the json library to convert this to a ruby hash. but my question still remains Commented Jul 13, 2015 at 7:47
  • @Зелёный please see edits Commented Jul 13, 2015 at 7:49
  • This is very similar to the output of group_by as in array.group_by{|a| a[:id]}. Commented Jul 13, 2015 at 9:33

3 Answers 3

3

This works(desctructive):

>> Hash[array.map { |x| [x.delete("id"), x] }]
=>{
    101=>{
        "first_name"=>"xxx",
        "last_name"=>"G",
        "email"=>"[email protected]",
        "phone_number"=>"555-555-5555"
    },
    102=>{
        "first_name"=>"Jen",
        "last_name"=>"P",
        "email"=>"[email protected]",
        "phone_number"=>"555-555-5555"
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't really return what the OP asked. It returns another Array of hashes, and it just wraps each original hash into a further hash. Other users have provided the right solution.
Since Ruby 2.1 it is also possible to use x.to_h instead of Hash[x]. Mostly aesthetic difference.
3

Try this:

array_h = Hash.new
array.each{|a| array_h[a["id"]] = a.reject{|e| e=='id' }}

#Output of array_h:
{
  101=>
    {
      "first_name"=>"xxx", 
      "last_name"=>"G", 
      "email"=>"[email protected]", 
      "phone_number"=>"555-555-5555"
    }, 
  102=>
    {
      "first_name"=>"Jen", 
      "last_name"=>"P", 
      "email"=>"[email protected]", 
      "phone_number"=>"555-555-5555"
    }
}

Note: This will not modify your original Array.

Comments

0

Non-destructive variant (preserves array) while removing "id":

{}.tap { |h| array.each { |a| nh = a.dup; h[nh.delete('id')] = nh } }
# => {101=>{"first_name"=>"xxx", "last_name"=>"G", "email"=>"[email protected]", "phone_number"=>"555-555-5555"}, 102=>{"first_name"=>"Jen", "last_name"=>"P", "email"=>"[email protected]", "phone_number"=>"555-555-5555"}} 
array
# => [{"id"=>101, "first_name"=>"xxx", "last_name"=>"G", "email"=>"[email protected]", "phone_number"=>"555-555-5555"}, {"id"=>102, "first_name"=>"Jen", "last_name"=>"P", "email"=>"[email protected]", "phone_number"=>"555-555-5555"}] 

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.