[ACCEPTED]-Ruby Hash Whitelist Filter-hashmap
Rails' ActiveSupport library also gives 3 you slice and except for dealing with the 2 hash on a key level:
y = x.slice("one", "two") # => { "one" => "one", "two" => "two" }
y = x.except("three") # => { "one" => "one", "two" => "two" }
x.slice!("one", "two") # x is now { "one" => "one", "two" => "two" }
These are quite nice, and 1 I use them all the time.
Maybe this it what you want.
wanted_keys = %w[one two]
x = { "one" => "one", "two" => "two", "three" => "three"}
x.select { |key,_| wanted_keys.include? key }
The Enumerable 5 mixin which is included in e.g. Array and 4 Hash provides a lot of useful methods like 3 select/reject/each/etc.. I suggest that 2 you take a look at the documentation for 1 it with ri Enumerable.
You can just use the built in Hash function 4 reject.
x = { "one" => "one", "two" => "two", "three" => "three"}
y = x.reject {|key,value| key == "three" }
y == { "one" => "one", "two" => "two"}
You can put whatever logic you want 3 into the reject, and if the block returns 2 true it will skip that key,value in the 1 new hash.
Improving a bit @scottd answer, if you are 4 using rails and have a list of what you 3 need, you can expand the list as parameters 2 from slice. For example
hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
hash.slice(*keys_whitelist)
And without rails, for 1 any ruby version, you can do the following:
hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
Hash[hash.find_all{|k,v| keys_whitelist.include?(k)}]
y = x.reject {|k,v| k == "three"}
0
Using a combination of everyone's answers 4 I have come up with this solution:
wanted_keys = %w[one two]
x = { "one" => "one", "two" => "two", "three" => "three"}
x.reject { |key,_| !wanted_keys.include? key }
=>{ "one" => "one", "two" => "two"}
Thanks 3 for your help guys!
EDIT:
The above works 2 in 1.8.7+
The following works in 1.9+ :
x.select 1 { |key,_| wanted_keys.include? key }
I'd use a lambda to filter. This will both 4 allow you to write complex filtering logic 3 & make it easy to test it. The fact 2 that the filtering logic is extracted will 1 allow to reuse it in other contexts.
ex:
x = { "one" => "one", "two" => "two", "three" => "three"}
matcher = ->(key,value) {
# FILTERING LOGIC HERE
!key[/three/]
}
x.select(&matcher) == { "one" => "one", "two" => "two"}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.