DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Array To Hash In Ruby

05.21.2005
| 128579 views |
  • submit to reddit
        Inspired by <a href="http://www.fivesevensix.com/articles/2005/05/20/array-to_h">something</a> Ryan Carver was trying to do:

a = [1, 2, 3]
Hash[*a.collect { |v|
    [v, v*2]
}.flatten]

It's not as foolproof as his solution, however!    

Comments

Snippets Manager replied on Wed, 2011/08/10 - 3:30pm

Thanks mmell. your code to convert array to ruby hash is very helpful.

Snippets Manager replied on Thu, 2009/10/15 - 4:28pm

no flattening required: class Array def to_hash(other) Hash[ *(0...self.size()).inject([]) { |arr, ix| arr.push(self[ix], other[ix]) } ] end end %W{ a b c }.to_hash( %W{ 1 2 3 } ) #=> {"a"=>"1", "b"=>"2", "c"=>"3"}

Snippets Manager replied on Wed, 2009/05/13 - 11:43am

But why is a de-referencing operator needed here? I don't get it either.

Snippets Manager replied on Wed, 2009/02/04 - 7:36am

Can someone please explain what that '*' sign is for in Hash[*a.collect { |v| [v, v*2] }.flatten] I dont understand that and i cannot sleep until I know what it is for.

Snippets Manager replied on Tue, 2008/05/06 - 3:14pm

Sorry, newbie here: class Array def flatten_once inject([]) { |v, e| v.concat(e)} end end

Snippets Manager replied on Tue, 2008/05/06 - 3:14pm

@ bradediger: I had trouble getting your flatten_once routine running. Here is my solution: class Array def flatten_once inject([]) { |v, e| v.concat(e)} end end

Snippets Manager replied on Thu, 2007/10/04 - 1:13pm

This should really use flatten_once, not flatten, so that you can do something like x.to_hash_keys{[]} and not have the [] flattened out. flatten_once is something like: class Array def flatten_once returning([]) {|ary| each{|x| ary.concat x}} end end

Snippets Manager replied on Mon, 2008/01/21 - 6:03pm

using zip to create a hash from a keys and a values array: class << Hash def create(keys, values) self[*keys.zip(values).flatten] end end gives: >> Hash.create(['a', 'b', 'c'], [1, 2, 3]) => {"a"=>1, "b"=>2, "c"=>3}

Snippets Manager replied on Wed, 2007/05/16 - 7:54pm

This helped me with a small challenge, of comparing two Arrays to each other, then generating a Hash of the results of that compare. Here's a little messing about in irb... >> id_list = (21..31).to_a => [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] >> products_ids = [24, 29, 30, 32] => [24, 29, 30, 32] >> results = Hash[*id_list.collect {|v| [v, products_ids.include?(v)]}.flatten] => {27=>false, 22=>false, 28=>false, 23=>false, 29=>true, 24=>true, 30=>true, 25=>false, 31=>false, 26=>false, 21=>false} >> results.each_pair {|k,v| puts "Key: #{k} is true!" if v == true} Key: 29 is true! Key: 24 is true! Key: 30 is true!

Snippets Manager replied on Thu, 2007/03/29 - 8:30am

I renamed therealadam's version to_hash_keys and added a counterpart to_hash_values. class Array def to_hash_keys(&block) Hash[*self.collect { |v| [v, block.call(v)] }.flatten] end def to_hash_values(&block) Hash[*self.collect { |v| [block.call(v), v] }.flatten] end end Then I can do this for example: >> a = ["able", "baker", "charlie"] >> a.to_hash_values {|v| a.index(v)} => {0=>"able", 1=>"baker", 2=>"charlie"}

Snippets Manager replied on Mon, 2012/05/07 - 2:12pm

Wow, that made my jaw drop. I remixed it as a member of Array and accepting a block to map array keys to Hash values. Just for kicks. class Array def to_h(&block) Hash[*self.collect { |v| [v, block.call(v)] }.flatten] end end

Snippets Manager replied on Mon, 2012/05/07 - 2:12pm

testing