Want to pick a certain set of key/value pairs from a Ruby hash? You might do this:
hash = {:foo => "bar", :bar => "baz", :baz => "boo"}
hash.select { |k,v| [:foo, :bar].include?(k) }
# returns [[:foo, "bar"], [:bar, "baz"]]
Kind of messy. We can do better by reopening the Hash class this way:
class Hash
def pick(*values)
select { |k,v| values.include?(k) }
end
end
Now our selection works like this:
hash = {:foo => "bar", :bar => "baz", :baz => "boo"}
hash.pick(:foo, :bar)
# returns [[:foo, "bar"], [:bar, "baz"]]
Ruby is a wonderful language. This is one small example of how having access to existing classes can be incredibly powerful. With this power comes great responsibility. Wield your power wisely.
Comments
3 responses to “Picking values from Ruby hashes”
If you’re using Rails, then ActiveSupport::CoreExtensions::Hash::Slice provides a slice() method to slice a hash, and this is automatically added to the Hash class for you. Its usage is exactly as given above, except that it returns a hash instead of an array of pairs.
You can use facets Hash method slice.
h.slice(:foo,:bar) #=> another hash
h.slice(:foo,:bar).to_a #=> to convert the hash into array.
http://facets.rubyforge.org/doc/index.html
How about:
class Hash
def pick(*values)
pairs = select { |k,v| values.include?(k) }
Hash[*pairs.flatten]
end
end
hash.pick(:foo, :bar)
#returns {:bar=>"baz", :foo=>"bar"}