Array#to_h
I found myself writing something like this far too often:
def map_something(array) hash = {} array.each do |a| hash[a] = lookup_value a end hash end
It bugged me every time, but digging through the Pick Axe never yielded (ahem) a simpler solution. What I wanted to do is this:
def map_something(array) array.to_h do |a| lookup_value a end end
But of course you'd need Array#to_h. Here's the cleverest implementation I could think of.
class Array def to_h(default=nil) Hash[ *inject([]) { |a, value| a.push value, default || yield(value) } ] end end
A pointless example:
a = [1, 2, 3] a.to_h do |v| [v * 2, v * 3] end > {1=>[2, 3], 2=>[4, 6], 3=>[6, 9]}
I love Array#inject!
There are 5 comments
And what about :
class Array def to_h(default=nil) inject({}) {|h,value| h[value] = default || yield(value); h } end endOnly slightly different ;)
How about this?
a = [1, 2, 3] Hash[*a.collect { |v| [v, v*2] }.flatten]Not quite as clean, but no new methods required.
Oops, try this (same, but with nicer formatting):
Note that
flattenobliterates the nested arrays so you end up with{1=>2, 2=>4, 3=>6}.Seems however you do it, it's not something I want to write a lot.. a strange case in Ruby that there's not a really elegant one-liner.
I fond myself building a hash using an object to find a key for it -- like this:
a = %w(hello world! how are you) a.inject({}) {|h, str| h[str.length] = str; h}So I use
class Enumerable def build_hash inject({}) {|h, o| h[yield o] = o; h} end endWhich is used like
[1, 2, 3].build_hash {|x| x * 2} #=> {2 => 1, 4 => 2, 6 => 3}