Misha Moroshko Misha Moroshko - 3 months ago 4
Ruby Question

How to remove a key from Hash and get the remaining hash in Ruby/Rails?

To add a new pair to Hash I do:

{:a => 1, :b => 2}.merge!({:c => 3}) # => {:a=>1, :b=>2, :c=>3}


Is there a similar way to delete a key from Hash ?

This works:

{:a => 1, :b => 2}.reject!{ |k| k == :a } # => {:b=>2}


but I would expect to have something like:

{:a => 1, :b => 2}.delete!(:a) # => {:b=>2}


It is important that the returning value will be the remaining hash, so I could do things like:

foo(my_hash.reject!{ |k| k == my_key }


in one line.

Answer

Rails has an except/except! method that returns the hash with those keys removed. If you're already using Rails, there's no sense in creating your own version of this.

class Hash
  # Returns a hash that includes everything but the given keys.
  #   hash = { a: true, b: false, c: nil}
  #   hash.except(:c) # => { a: true, b: false}
  #   hash # => { a: true, b: false, c: nil}
  #
  # This is useful for limiting a set of parameters to everything but a few known toggles:
  #   @person.update(params[:person].except(:admin))
  def except(*keys)
    dup.except!(*keys)
  end

  # Replaces the hash without the given keys.
  #   hash = { a: true, b: false, c: nil}
  #   hash.except!(:c) # => { a: true, b: false}
  #   hash # => { a: true, b: false }
  def except!(*keys)
    keys.each { |key| delete(key) }
    self
  end
end
Comments