2012-10-12 53 views
5

No puedo encontrar la manera de eliminar las claves de un hash que no están en una matriz determinada de nombres de teclas. Leí que puedo usar except o slice, pero ¿cómo puedo darles una lista de los nombres clave que quiero conservar? Así, por ejemplo, si tuviera este hash:Eliminar claves en el hash no en el conjunto

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

y yo sólo quería mantener, por ejemplo, :title, :media y :localeLanguage, ¿cómo podría mantener sólo aquellos valores cuyos nombres clave especifico?

Respuesta

17

Usaría keep_if (requiere 1.9.2).

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

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

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

¡Maravilloso! Gracias Thomas, esto es genial. No sabía sobre '.keep_if'. ¿Es esto solo Ruby 1.9.x? Ah. Veo que lo has editado para aclarar eso. Gracias. – kakubei

+1

En este caso, se lee bien. Algunas personas [no me gusta] (http://news.ycombinator.com/item?id=2247352). –

4

en Ruby 1.9.3:

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

en Ruby 1.8.7, almohadilla # SELECT devuelve una matriz de matrices, a fin de utilizar Hash [] para convertir esa matriz en un hash:

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

La diferencia en el orden se debe a que, en Ruby 1.8.7, los valores hash están desordenados.

+1

Gracias por poner soluciones para ambos 1.9.3 y 1.8.7. Muy útil ya que podría tener que convertir el código a 1.8.7 en algún momento (¡con suerte no!) – kakubei

14

En Rails 4+, utilice 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"} 

Uso slice! para modificar su tabla hash en su lugar.

Cuestiones relacionadas