Kostas
Kostas

Reputation: 8585

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">,
  ...
}

Upvotes: 34

Views: 39703

Answers (3)

Jon Snow
Jon Snow

Reputation: 11882

You can simply using numbered parameter syntax of the Ruby 2.7+ :

users_by_id = User.all.to_h { [_1.id, _1] }

Note. In Ruby 3.4 + simply use it for the named parameter :

users_by_id = User.all.to_h { [it.id, it] }

Upvotes: 2

tokland
tokland

Reputation: 67850

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)

Upvotes: 80

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230296

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

Upvotes: 7

Related Questions