Hash remove all except specific keys

Ruby on-RailsRubyRuby on-Rails-3

Ruby on-Rails Problem Overview


I would like to remove every key from a hash except a given key.

For example:

{
 "firstName": "John",
 "lastName": "Smith",
 "age": 25,
 "address":
 {
     "streetAddress": "21 2nd Street",
     "city": "New York",
     "state": "NY",
     "postalCode": "10021"
 },
 "phoneNumber":
 [
     {
       "type": "home",
       "number": "212 555-1234"
     },
     {
       "type": "fax",
       "number": "646 555-4567"
     }
 ]
}

I want to remove everything except "firstName" and/or "address"

Thanks

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

What about slice?

hash.slice('firstName', 'lastName')
 # => { 'firstName' => 'John', 'lastName' => 'Smith' }

Solution 2 - Ruby on-Rails

Some other options:

h.select {|k,v| ["age", "address"].include?(k) }

Or you could do this:

class Hash
  def select_keys(*args)
    select {|k,v| args.include?(k) }
  end
end

So you can now just say:

h.select_keys("age", "address")

Solution 3 - Ruby on-Rails

Hash#select does what you want:

   h = { "a" => 100, "b" => 200, "c" => 300 }
   h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
   h.select {|k,v| v < 200}  #=> {"a" => 100}

Edit (for comment):

assuming h is your hash above:

h.select {|k,v| k == "age" || k == "address" }

Solution 4 - Ruby on-Rails

If you use Rails, please consider ActiveSupport except() method: http://apidock.com/rails/Hash/except

hash = { a: true, b: false, c: nil}
hash.except!(:c) # => { a: true, b: false}
hash # => { a: true, b: false }

Solution 5 - Ruby on-Rails

hash = { a: true, b: false, c: nil }
hash.extract!(:c) # => { c: nil }
hash # => { a: true, b: false }

Solution 6 - Ruby on-Rails

Inspired by Jake Dempsey's answer, this one should be faster for large hashes, as it only peaks explicit keys rather than iterating through the whole hash:

class Hash
  def select_keys(*args)
    filtered_hash = {}
    args.each do |arg|
      filtered_hash[arg] = self[arg] if self.has_key?(arg)
    end
    return filtered_hash
  end
end

Solution 7 - Ruby on-Rails

No Rails needed to get a very concise code:

keys = [ "firstName" , "address" ]
# keys = hash.keys - (hash.keys - keys) # uncomment if needed to preserve hash order
keys.zip(hash.values_at *keys).to_h

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionglarkouView Question on Stackoverflow
Solution 1 - Ruby on-RailsMario UherView Answer on Stackoverflow
Solution 2 - Ruby on-RailsJake DempseyView Answer on Stackoverflow
Solution 3 - Ruby on-RailsJim DevilleView Answer on Stackoverflow
Solution 4 - Ruby on-RailsasiniyView Answer on Stackoverflow
Solution 5 - Ruby on-Railsar31anView Answer on Stackoverflow
Solution 6 - Ruby on-RailsstarkovvView Answer on Stackoverflow
Solution 7 - Ruby on-RailsribamarView Answer on Stackoverflow