2012-02-01 50 views
14

¿Cómo podría eliminar una matriz de claves en un hash? Por ejemplo, puede llamar a:Eliminar matriz de claves en Ruby Hash

hash_array.delete(some_key) 

Pero ¿cómo se puede hacer esto:

hash_array.delete([key1,key2,key3,...]) 

sin bucle a través de la matriz innecesariamente.

+0

Si tiene una matriz entonces usted iterar a través de él, en cualquier caso. Tal vez no necesite almacenar estas claves en una matriz, sino eliminarlas inmediatamente. – megas

Respuesta

14

Usted puede iterar sobre una matriz de claves y borrar cada uno de ellos:

[key1, key2, key3].each { |k| some_hash.delete k } 

No puedo recordar ninguna solución mejor.

+0

Estoy tratando de mantenerme alejado de los bucles porque son lentos y este código es sensible al tiempo. –

+1

Veo, pero si maneja una matriz de claves, debe iterar sobre ella de todos modos. ¿Cuáles son los tamaños de hash y array en tu caso? –

+0

Realmente no necesito iterar a través de la matriz de claves, solo necesito eliminar esas claves en el hash. El hash tiene aproximadamente 20,000 elementos pero tiene que repetirse varias veces con elementos que son diferentes cada vez. –

2

Tal vez merece la pena hacer un método

class Hash 
    def delete_by_keys *keys 
    keys.each{|k| delete(k)} 
    end 
end 

hash_array.delete_by_keys(key1,key2,..) 
+0

Puede ser útil. Gracias. –

+1

'' 'keys.map''' en lugar de' '' keys.each''' devuelve la matriz de valores eliminados. útil. – kuboon

10

Usted puede tratar de utilizar Hash#delete_if:

delete_if borra todos los par clave-valor de SAS el bloque para el que se evalúa como verdadera.

array_hash.delete_if { |key, _| [key1, key2, key3].include? key } 

ACTUALIZACIÓN Si no desea iterar sobre matriz de claves, se puede utilizar en lugar de SetArray (ya Set utiliza como almacenamiento Hashinclude? es O (1)) :

require 'set' 
keys = [key1,key2,key3].to_set 
array_hash.delete_if { |key, _| keys.include? key } 
+0

+1. Solo iba a agregar esto. Por supuesto, itera a través de los elementos también (incluso varias veces). –

+0

Si el tamaño del hash es mucho mayor que el tamaño de la matriz, este enfoque es menos eficiente que iterar sobre una matriz. –

+1

@ KL-7, de acuerdo, siempre se requiere hacer pruebas de rendimiento antes de optimizar algún código, la optimización sin medición puede aumentar el tiempo de ejecución y el consumo de memoria. No me molestaría en optimizar un código como este. OP solo tiene varias alternativas :) –

1

Usted puede lograr lo que se propone hacer con el "operador splat" (*).

hash_array.delete *[key1,key2,key3,...] 

Esto es el equivalente a pasar cada tecla como un argumento separado.

+3

se ve bastante bien pero no funciona ... –

+1

tampoco funciona para mí – traHfo

8

Esto es exactamente lo que está buscando ... Puede hacerlo así sin tener que recorrer la matriz innecesariamente.

keys_to_delete = [key1, key2, key3] 
hash_array.except!(*keys_to_delete) 

El resultado se almacena en hash_array

+5

Esto es parte de los rieles, no del rubí. – sokkyoku

Cuestiones relacionadas