Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Array of objects to Hash with a field as the key

I have an Array of objects:

[
  #<User id: 1, name: "Kostas">,
  #<User id: 2, name: "Moufa">,
  ...
]

And I want to convert this into an Hash with the id as the keys and the objects as the values. Right now I do it like so but I know there is a better way:

users = User.all.reduce({}) do |hash, user|
  hash[user.id] = user
  hash
end

The expected output:

{
  1 => #<User id: 1, name: "Kostas">,
  2 => #<User id: 2, name: "Moufa">,
  ...
}
like image 621
Kostas Avatar asked Apr 02 '13 10:04

Kostas


People also ask

How do you turn an array into a hash in Ruby?

The to_h method is defined in the array class. It works to convert an array to a hash in the form of key-value pairs. The method converts each nested array into key-value pairs. The method also accepts a block.

How do you create an array of hashes?

Creating an array of hashes You are allowed to create an array of hashes either by simply initializing array with hashes or by using array. push() to push hashes inside the array. Note: Both “Key” and :Key acts as a key in a hash in ruby.

How do I turn an array into a map?

To convert an array of objects to a Map , call the map() method on the array and on each iteration return an array containing the key and value. Then pass the array of key-value pairs to the Map() constructor to create the Map object.

Is an array a hash?

With arrays, the key is an integer, whereas hashes support any object as a key. Both arrays and hashes grow as needed to hold new elements. It's more efficient to access array elements, but hashes provide more flexibility.


2 Answers

users_by_id = User.all.map { |user| [user.id, user] }.to_h 

If you are using Rails, ActiveSupport provides Enumerable#index_by:

users_by_id = User.all.index_by(&:id) 
like image 58
tokland Avatar answered Oct 11 '22 10:10

tokland


You'll get a slightly better code by using each_with_object instead of reduce.

users = User.all.each_with_object({}) do |user, hash|
  hash[user.id] = user
end
like image 41
Sergio Tulentsev Avatar answered Oct 11 '22 10:10

Sergio Tulentsev