12

I can't find a way to remove keys from a hash that are not in a given array of key names. I read that I can use except or slice, but how can I feed them a list of the key names I want to keep? So for example, if I had this hash:

entry = {:title=>"casablanca", :media=>"dvd", :localeLanguage=>"en", :imdb=>"", :freebase=>"", :originalTitle => 'casablanca', :season=> '1', :episode => '3'}

and I only wanted to keep, say, :title, :media and :localeLanguage, how could I keep only those values whose key names I specify?

3 Answers 3

26

In Rails 4+, use slice:

entry = {:title=>"casablanca", :media=>"dvd", :localeLanguage=>"en", :imdb=>"", :freebase=>"", :originalTitle => 'casablanca', :season=> '1', :episode => '3'}
keepers = [:title, :media, :localeLanguage]

entry.slice(*keepers)
# => {:title=>"casablanca", :media=>"dvd", :localeLanguage=>"en"}

Shorter version (with same result):

entry.slice(*%i(title media localeLanguage))

Use slice! to modify your hash in-place.

Sign up to request clarification or add additional context in comments.

Comments

22

I'd use keep_if (requires 1.9.2).

keepers = [:title, :media, :localeLanguage]

entry.keep_if {|k,_| keepers.include? k }

#=> {:title=>"casablanca", :media=>"dvd", :localeLanguage=>"en"}      

2 Comments

Wonderful! Thanks Thomas, this is great. I didn't know about .keep_if. Is this only Ruby 1.9.x? Ah. I see you edited it to clarify that. Thanks.
In this case, it reads well. Some people don't like it.
4

In Ruby 1.9.3:

entry = entry.select do |key, value|
  [:title, :media, :localeLanguage].include?(key)
end
p entry
# => {:title=>"casablanca", :media=>"dvd", :localeLanguage=>"en"}

In Ruby 1.8.7, Hash#select returns an array of arrays, so use Hash[] to turn that array into a hash:

entry = Hash[
  entry.select do |key, value|
    [:title, :media, :localeLanguage].include?(key)
  end
]
# => {:media=>"dvd", :localeLanguage=>"en", :title=>"casablanca"}

The difference in order is because, in Ruby 1.8.7, Hashes are unordered.

1 Comment

Thanks for putting solutions for both 1.9.3 and 1.8.7. Quite useful since I might have to convert the code to 1.8.7 at some point (hopefully not!)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.