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


Hello Jacius!!!

Really good one liners.
But why don't do with_only like this:

def with_only( *keys )
select{ |k,v| keys.include?(k) }
end

I guess reject + not is the same as select....

See ya



Comments are closed.

Previous post: Snippet: Range#compare Next post: Migrating projects to Git