class Array
def to_h
hash = {}
self.each do |entry|
hash[entry[0]] = entry[1]
# Yes, we could write: key, value = entry,
# but it isn't optimized, to_h must be optimized,
# because it's a very little method
end
hash
end
end
p [['a', '1'], ['b', '2']].to_h
# {"a"=>"1", "b"=>"2"}
Refactorings
No refactoring yet !
Joran Jessurun
October 22, 2008, October 22, 2008 11:03, permalink
I think the Hash[value, value, ...] method does what you want.
a = [['a', '1'], ['b', '2']]
p Hash[*a.flatten]
# => {"a"=>"1", "b"=>"2"}
Dmitry Polushkin
October 22, 2008, October 22, 2008 14:17, permalink
Thanks! Why no "to_h" method in ruby Hash native class? Inverting to_a changes? {:a => 1, :b => 2}.to_a.to_h
danielharan
October 22, 2008, October 22, 2008 14:19, permalink
[['a', '1'], ['b', '2']].inject({}) {|hash,i| k,v = i; hash[k] = v; hash}
Dmitry Polushkin
October 22, 2008, October 22, 2008 14:24, permalink
@danielharan: is it faster than Hash[*a.flatten] ?
danielharan
October 22, 2008, October 22, 2008 14:41, permalink
Actually, I assumed it was in ActiveSupport because it wasn't working for me; turns out I wasn't using * on the array.
In some cases you can't use the first idiom. In any case, what's the obsession with optimization?
a = [['a', '1'], ['b', '2', '3']]
p Hash[*a.flatten]
ArgumentError: odd number of arguments for Hash
from (irb):15:in `[]'
from (irb):15
from :0
# And come to realize it, my refactoring doesn't work either in that case, but this does:
[['a', '1'], ['b', '2', '3']].inject({}) {|hash,i| hash[i.shift] = i; hash}
=> {"a"=>["1"], "b"=>["2", "3"]}
Adam
October 22, 2008, October 22, 2008 15:26, permalink
require 'activesupport' ActiveSupport::OrderedHash.new([['a', '1'], ['b', '2']]).to_hash
Dmitry Polushkin
October 22, 2008, October 22, 2008 18:21, permalink
Something like I have written for the refactoring: http://github.com/rails/rails/tree/master/activesupport/lib/active_support/ordered_hash.rb#L37
I think I will use native activesupport OrderedHash class for converting to_hash...
@danieharan: yes, in some cases I cant, but this array I'm getting from the Asset.count(:group => 'column_type'), so it's fixed width with two values: column_type + count value. By the benchmark it's not very optimized, and also it's not so simple, that it might be.
@Adam: I don't need the ordering, but anyway it's good that activesupport have that class. But why native Array class doesn't have to_h or to_hash? Strange for me.
Conversion from the 2d array to hash.