HiveBrain v1.2.0
Get Started
← Back to all entries
snippetrubyrailsCritical

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

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
keyhowfromandremainingremovetherubyhashrails

Problem

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.

Solution

For those of you who just came here to know how to delete a key/value pair from a hash, you can use:

hash.delete(key)

For the rest of you who came here to read a wall of text about something entirely different, you can read the rest of this 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

Code Snippets

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

Context

Stack Overflow Q#6227600, score: 921

Revisions (0)

No revisions yet.