Skip to content

Instantly share code, notes, and snippets.

@redconfetti
Last active January 20, 2017 00:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redconfetti/e0d12aef119ad62ef0d2 to your computer and use it in GitHub Desktop.
Save redconfetti/e0d12aef119ad62ef0d2 to your computer and use it in GitHub Desktop.
Convert Array to Indexed Hash
# Often you'll have an array of hashes, and you find yourself needing to
# retrieve an object from that array by some unique attribute of the hash.
#
# Here is a way to convert an array to a hash that contains hashes indexed by the key value you specify.
# This is possible because Array uses the Enumerable module as a mixin
users = [
{'id' => 1, 'name' => 'Susan'},
{'id' => 2, 'name' => 'Pat'},
{'id' => 3, 'name' => 'Jason'}
]
search_user_hash = users.inject({}) { |map, user| map[user['id']] = user; map}
# search_user_hash = {
# 10932=>{"id"=>10932, "name"=>"Joe"},
# 10936=>{"id"=>10936, "name"=>"Susan"},
# 10943=>{"id"=>10943, "name"=>"Dan"}
# }
# joe = search_user[10932]
# susan = search_user_hash[10943]
@jemminger
Copy link

Shouldn't the example:

# search_user_hash = {
#   1=>{"id"=>10932, "name"=>"Joe"},
#   2=>{"id"=>10936, "name"=>"Susan"},
#   3=>{"id"=>10943, "name"=>"Dan"}
# }

be this?

# search_user_hash = {
#   10932=>{"id"=>10932, "name"=>"Joe"},
#   10936=>{"id"=>10936, "name"=>"Susan"},
#   10943=>{"id"=>10943, "name"=>"Dan"}
# }

@snowe2010
Copy link

Yeah I'm definitely confused about what is going on here.

@madhatter
Copy link

Does not seem to work everywhere as expected...:

 search_user_hash = users.inject({}) { |map, user| map[user['id']] = user; map}
=> {1=>{"id"=>1, "name"=>"Susan", 2=>{"id"=>2, "name"=>"Pat", 3=>{"id"=>3, "name"=>"Jason"}}},
 2=>{"id"=>2, "name"=>"Pat", 3=>{"id"=>3, "name"=>"Jason"}},
 3=>{"id"=>3, "name"=>"Jason"}}

@LeFnord
Copy link

LeFnord commented Apr 15, 2015

perhaps you want this:

users = [{"id"=>1, "name"=>"Susan"}, {"id"=>2, "name"=>"Pat"}, {"id"=>3, "name"=>"Jason"}]
# => [{"id"=>1, "name"=>"Susan"}, {"id"=>2, "name"=>"Pat"}, {"id"=>3, "name"=>"Jason"}]
users.group_by{|x| x["id"]}
# => {1=>[{"id"=>1, "name"=>"Susan"}], 2=>[{"id"=>2, "name"=>"Pat"}], 3=>[{"id"=>3, "name"=>"Jason"}]}

@redconfetti
Copy link
Author

@jemminger, yeah. You're right. My example output was off. I fixed it.

@LeFnord - Yeah. That's a nice approach too, but if you know that the 'id' is unique, then you can avoid working with arrays when accessing the resulting hash by ID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment