832ed6ace46d61032151f4e1864c057f

Conversion from the 2d array to hash.

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 !

8a5ceb33f545ea53db6b7832bf999846

Joran Jessurun

October 22, 2008, October 22, 2008 11:03, permalink

2 ratings. Login to rate!

I think the Hash[value, value, ...] method does what you want.

a = [['a', '1'], ['b', '2']]
p Hash[*a.flatten]
# => {"a"=>"1", "b"=>"2"}
832ed6ace46d61032151f4e1864c057f

Dmitry Polushkin

October 22, 2008, October 22, 2008 14:17, permalink

No rating. Login to rate!

Thanks! Why no "to_h" method in ruby Hash native class? Inverting to_a changes? {:a => 1, :b => 2}.to_a.to_h

880cbab435f00197613c9cc2065b4f5a

danielharan

October 22, 2008, October 22, 2008 14:19, permalink

No rating. Login to rate!
[['a', '1'], ['b', '2']].inject({}) {|hash,i| k,v = i; hash[k] = v; hash}
832ed6ace46d61032151f4e1864c057f

Dmitry Polushkin

October 22, 2008, October 22, 2008 14:24, permalink

No rating. Login to rate!

@danielharan: is it faster than Hash[*a.flatten] ?

880cbab435f00197613c9cc2065b4f5a

danielharan

October 22, 2008, October 22, 2008 14:41, permalink

No rating. Login to rate!

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"]}
A8d3f35baafdaea851914b17dae9e1fc

Adam

October 22, 2008, October 22, 2008 15:26, permalink

1 rating. Login to rate!
require 'activesupport'
ActiveSupport::OrderedHash.new([['a', '1'], ['b', '2']]).to_hash
832ed6ace46d61032151f4e1864c057f

Dmitry Polushkin

October 22, 2008, October 22, 2008 18:21, permalink

No rating. Login to rate!

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.

Your refactoring





Format Copy from initial code

or Cancel