34

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">,
  ...
}
1
  • 1
    @SergioTulentsev, I was looking at Enumerable#group_by and it was almost what I'm looking for. I just thought there is a version of it the instead of building arrays for values, it is more agressive and keeps only one value. Commented Apr 2, 2013 at 10:10

3 Answers 3

80
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)
Sign up to request clarification or add additional context in comments.

2 Comments

I personally prefer the mash way instead of the Hash[...] one. It read cleaner, more ruby-like.
I believe your Ruby >= 2.1 needs a slight correction, you want .to_h not .to_a e.g. users = User.all.map { |u| [u.id, u] }.to_h
7

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

2 Comments

Are we going to go the inject/each_with_object/Hash/mash path again? :-) bugs.ruby-lang.org/issues/show/666
@tokland: Yes, that was the first thought in my head when I saw your comment :)
3

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] }

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.