1

I want to modify my array of hashes to facilitate better search performance

I have:

a = [ {"id" => 1, "name" => "Matt", "email" => "[email protected]"}, {"id" => 2, "name" => "Charlie", "email" => "[email protected]"} ]

I want to transform this into:

b = [ {1 => { "name" => "Matt", "email" => "[email protected]"}},{2 => { "name" => "Charlie", "email" => "[email protected]"}} ]

Note that the "id" field won't necessarily be a sequential or contiguous set, but each occurrence will be unique. Also, the hash nested as a value in b can contain 'id' key/value pair if that makes things easier.

3 Answers 3

2

Try:

a.map{|record| the_id = record.delete("id"); {the_id => record}}
Sign up to request clarification or add additional context in comments.

3 Comments

This will create an array of 1-element hashes of hash-objects, not a hash of hash-objects as the OP wishes (i.e. it will just wrap each individual hash-object into its own private little hash).
This will modify the content of the original a array
@Amadan Matt does ask for an array of hashes… Although he is probably confused.
2

To get the array you describe:

b = a.map {|i| { i["id"] => i } }

But note that if you are doing this to perform efficient searches by id then build a hash instead of an array:

b = a.inject({}) {|h,i| h[i["id"]]=i; h}

2 Comments

@Matt Did you make sure you ran this in a fresh Ruby? Amadan’s first answer as well as Nate Murray’s will trash your a array so that my answer does not work anymore.
My apologies, I did indeed.
1
a.each_with_object({}) { |x, h| h[x.delete('id')] = x }

This will construct a new hash ({}), pass it into the block as h with each element x. In the block x.delete('id') removes the id key/value from x, and returns it so it can be used as the index to assign a value to the resultant h hash.

EDIT per kmkaplan's comment: If you still need the original array, use this:

a.each_with_object({}) { |x, h| c = x.clone; h[c.delete('id')] = c }

EDIT per kmkaplan's other comment: If the OP really isn't confused, Nate Murray's answer is the right one.

1 Comment

This will modify the content of the original a array.

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.