Hash remove all except specific keys
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")
How to remove a key from Hash and get the remaining hash in Ruby/Rails?
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
Remove a Hash key using except
You will have to use this to get the my_hash['user_attrbiutes'] except person_attributes
:
2.1.0 :010 > my_hash['user_attributes'].except('person_attributes')
=> {"email"=>"email@email.com"}
To get the output as {"user_attributes"=>{"email"=>"email@email.com"}}
you can use:
=> {"user_attributes"=>{"email"=>"email@email.com", "person_attributes"=>{"first_name"=>"a_name", "last_name"=>"a_name"}}}
2.1.0 :026 > my_hash['user_attributes'].delete('person_attributes')
=> {"first_name"=>"a_name", "last_name"=>"a_name"}
2.1.0 :027 > my_hash
=> {"user_attributes"=>{"email"=>"email@email.com"}}
remove specific keys (and values) from a ruby hash
Hash#except
, Hash#except!
do not accepts an array of keys, but keys as arbitrary parameters. You need to use *
operator to convert the array into method arguments:
result_hash.except(*suppression_list)
Is there an elegant way to remove a specific key from a hash and it's sub-hashes in Ruby
I don't think there is a built in method for this so a simple recursive method along the following lines is one solution:
def recursive_delete(hash, to_remove)
hash.delete(to_remove)
hash.each_value do |value|
recursive_delete(value, to_remove) if value.is_a? Hash
end
end
With your example data:
h = { :action => "index", :controller => "home", :secret => "I love Jeff Atwood",
:user => {:name => "Steve", :secret => "I steal Joel's pants"}}
recursive_delete(h, :secret)
puts h.inspect
Gives:
{:controller=>"home", :user=>{:name=>"Steve"}, :action=>"index"}
Note that this solution works in place i.e. it is modifying the original Hash, not returning a new Hash with the requested key excluded.
Delete all similar keys from nested hash
You can write a function to recursively traverse Hashes and Arrays.
def delete_recursively(thing, key_to_delete)
case thing
when Hash
# Delete the key
thing.delete(key_to_delete)
# Recurse into each remaining hash value.
thing.each_value do |value|
delete_recursively(value, key_to_delete)
end
when Array
# Recurse into each value of the array.
thing.each do |value|
delete_recursively(value, key_to_delete)
end
end
end
This can be expanded to include other data types as necessary.
Related Topics
Download and Write .Tar.Gz Files Without Corruption
Using Rvm, But Can't Set Current Ruby Version (Ubuntu 11.10)
Gem Install Rails Does Not Install Rails
How Does Rake Db::Migrate Actually Work
I Can't Remove Whitespaces from a String Parsed by Nokogiri
How to Read Post Data in Rack Request
Normal Variables VS Instance Variable in Ruby, Whats the Difference
How to Create Pretty JSON in Chef (Ruby)
How to Run Multiple Lines of Ruby in HTML.Erb File
Turn a Ruby Hash into HTML List
Properly Using Log4R in Ruby Application
How to Parse a HTML Table with Nokogiri
How to Connect to a Mongodb from Ruby Code
Append Row to CSV File Ruby 1.9 CSV Lib
How to Extend a Class from an Initializer and Have It Reload in Development Environment