2

Possible Duplicate:
Combine two Arrays into Hash

I have an model which stores key value pairs as attributes for another model person.

What is a simple way of turning person.person_attributes into a hash?

This is a stupid way I came up with:

keys = person.person_attributes.map(&:key)
values = person.person_attributes.map(&:value)

hashed_attributes = Hash.new

keys.each_index do |i|
  hashes_attribues[keys[i]] = values[i]
end

What is a more elegant way to do this?

Thank you in advance,

Community
  • 1
  • 1
rickypai
  • 4,016
  • 6
  • 26
  • 30
  • possible duplicate of [Combine two Arrays into Hash](http://stackoverflow.com/questions/5174913/combine-two-arrays-into-hash) or http://stackoverflow.com/questions/3359659/how-to-build-a-ruby-hash-out-of-two-equally-sized-arrays – Sully Oct 04 '12 at 22:01
  • It's not an exact duplicate - my understanding is that there is only one array (`person_attributes`) and we need to build a hash from methods called on the items in that array. – Andrew Haines Oct 04 '12 at 22:17

2 Answers2

4

I like Enumerable#each_with_object for these sort of things

attributes = person.person_attributes.each_with_object({}) do |attribute, hash|
  hash[attribute.key] = attribute.value
end

If you're still on Ruby 1.8.7, not to worry, Rails has backported this method.

Andrew Haines
  • 6,574
  • 21
  • 34
2

You want to turn an array of objects, each with a key and value property, into a hash where the key maps to the value?

You can use the following, which uses Hash[array] to turn a two-dimensional array into a hash:

Hash[person.person_attributes.map { |e| [e.key, e.value] }]

Input:

Obj = Struct.new(:key, :value)

[ { Obj.new(:key1, :value1) },
  { Obj.new(:key2, :value2) },
  { Obj.new(:key3, :value3) }
]

Output:

{ :key1 => :value1, :key2 => :value2, :key3 => :value3 }
user229044
  • 232,980
  • 40
  • 330
  • 338