2012-10-12 14 views
5

Nie mogę znaleźć sposobu na usunięcie kluczy z hasza, które nie znajdują się w danej tablicy nazw kluczy. Czytałem, że mogę używać except lub slice, ale jak mogę podać im listę kluczowych nazw, które chcę zachować? Tak na przykład, gdybym miał ten hash:Usuwanie kluczy w haszowaniu nie w tablicy

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

a ja tylko chciałem zachować, powiedzmy, :title, :media i :localeLanguage, w jaki sposób mogę zachować tylko te wartości, których nazwy klucz określić?

Odpowiedz

17

Użyłbym keep_if (wymaga 1.9.2).

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

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

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

Cudownie! Dzięki Thomas, to jest świetne. Nie wiedziałem o '.keep_if'. Czy to jest tylko Ruby 1.9.x? Ah. Widzę, że to zredagowałeś, żeby to wyjaśnić. Dzięki. – kakubei

+1

W tym przypadku dobrze się czyta. Niektórzy ludzie [nie lubią tego] (http://news.ycombinator.com/item?id=2247352). –

4

W Ruby 1.9.3:

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

W Ruby 1.8.7, krzyżyka # select tablicę tablic więc używać Hash [] kolei, że układ do mieszania:

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

Różnica w kolejności jest spowodowana tym, że w Ruby 1.8.7 hashe są nieuporządkowane.

+1

Dziękujemy za umieszczenie rozwiązań dla wersji 1.9.3 i 1.8.7. Bardzo przydatne, ponieważ może będę musiał przekonwertować kod na 1.8.7 w pewnym momencie (mam nadzieję, że nie!) – kakubei

14

W Rails 4+, użyj 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"} 

Zastosowanie slice! zmodyfikować skrót na miejscu.

Powiązane problemy