Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array to hash of key value pairs in ruby

From a model that returns all the values from a table, how would I convert that to a hash of name value pairs

{column_value => column_value}

e.g.

[{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]

to (specifying :id and :name)

{'first' => 1, 'second' => 2, 'third' => 3}
like image 612
Christopher Avatar asked Dec 02 '09 21:12

Christopher


2 Answers

You can do it in one line with inject:

a = [{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
a.inject({}) { |sum, h| sum.merge({ h[:name] => h[:id]}) }
# => {"third" => 3, "second" => 2, "first" => 1}
like image 92
James A. Rosen Avatar answered Nov 04 '22 17:11

James A. Rosen


The following approach is reasonably compact, yet still readable:

def join_rows(rows, key_column, value_column)
  result = {}
  rows.each { |row| result[row[key_column]] = row[value_column] }
  result
end

Usage:

>> rows = [{:id => 1, :name => 'first'}, {:id => 2, :name => 'second'}, {:id => 3, :name => 'third'}]
>> join_rows(rows, :name, :id)
=> {"third"=>3, "second"=>2, "first"=>1}

Or, if you want a one-liner:

>> rows.inject({}) { |result, row| result.update(row[:name] => row[:id]) }
=> {"third"=>3, "second"=>2, "first"=>1}
like image 43
Pär Wieslander Avatar answered Nov 04 '22 19:11

Pär Wieslander