Snippet: Hash#with_only, #merge_existing
Here are some potentiall useful one-liner methods for extracting and merging only parts of Hashes. I was surprised to find out that Hash didn't already have built-in methods to do these things. Maybe they're considered so obvious that they don't need to be built-in, but I think the readability gain is worth it.
class Hash
# Return a copy of the receiver with only the given keys.
#
# >> {:a => 1, :b => 2, :c => 3}.with_only(:a, :c)
# => {:a => 1, :c => 3}
#
def with_only( *keys )
reject { |k,v| not keys.include?(k) }
end
# Return a copy of the receiver without the given keys.
#
# >> {:a => 1, :b => 2, :c => 3}.without(:a, :c)
# => {:b => 2}
#
def without( *keys )
reject { |k,v| keys.include?(k) }
end
# Like #merge, but only accepts keys that the receiver already has.
#
# >> {:a => 1, :b => 2}.merge_existing({:a => 0, :c => 0})
# => {:a => 0, :b => 2}
#
def merge_existing( other )
merge( other.with_only(*self.keys) )
end
# Like #merge_existing, but modifies the receiver.
#
def merge_existing!( other )
merge!( other.with_only(*self.keys) )
end
alias :update_existing :merge_existing!
end
Comments
on
Hello Jacius!!!
Really good one liners.
But why don't do with_only like this:
I guess reject + not is the same as select....
See ya
on
That was my first thought as well. But strangely, Hash#select doesn't return a Hash, it returns nested arrays, like
[[:a, 1], [:b, 2]]
. So, using reject turned out to be the simplest way.Comments are closed.