Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleanest way to create a Hash from an Array

I seem to run into this very often. I need to build a Hash from an array using an attribute of each object in the array as the key.

Lets say I need a hash of example uses ActiveRecord objecs keyed by their ids Common way:

ary = [collection of ActiveRecord objects] hash = ary.inject({}) {|hash, obj| hash[obj.id] = obj } 

Another Way:

ary = [collection of ActiveRecord objects] hash = Hash[*(ary.map {|obj| [obj.id, obj]}).flatten] 

Dream Way: I could and might create this myself, but is there anything in Ruby or Rails that will this?

ary = [collection of ActiveRecord objects] hash = ary.to_hash &:id #or at least hash = ary.to_hash {|obj| obj.id} 
like image 346
Daniel Beardsley Avatar asked Jan 05 '09 10:01

Daniel Beardsley


People also ask

How do you turn an array into a hash?

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.

Can you hash an array in Java?

hashCode(Object[]) method returns a hash code based on the contents of the specified array. If the array contains other arrays as elements, the hash code is based on their identities rather than their contents. For any two arrays a and b such that Arrays.

Which one is a difference between an array and 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.

What is TO_H in Ruby?

Ruby | Array to_h() function Array#to_h() : to_h() is a Array class method which returns the result of interpreting ary as an array of [key, value] pairs. Syntax: Array.to_h() Parameter: Array. Return: the result of interpreting ary as an array of [key, value] pairs.


2 Answers

There is already a method in ActiveSupport that does this.

['an array', 'of active record', 'objects'].index_by(&:id) 

And just for the record, here's the implementation:

def index_by   inject({}) do |accum, elem|     accum[yield(elem)] = elem     accum   end end 

Which could have been refactored into (if you're desperate for one-liners):

def index_by   inject({}) {|hash, elem| hash.merge!(yield(elem) => elem) } end 
like image 101
August Lilleaas Avatar answered Sep 20 '22 21:09

August Lilleaas


a shortest one?

# 'Region' is a sample class here # you can put 'self.to_hash' method into any class you like   class Region < ActiveRecord::Base   def self.to_hash     Hash[*all.map{ |x| [x.id, x] }.flatten]   end end 
like image 24
zed_0xff Avatar answered Sep 22 '22 21:09

zed_0xff