Reputation: 8585
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
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
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
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