example - ruby create hash
Ruby: divide un hash en dos en funciĆ³n de las claves deseadas (5)
Espero que esta pregunta tenga una respuesta muy simple. Puedo pensar en maneras de aburrirme, molesto bucle, pero espero que haya una solución más elegante.
Si tengo las siguientes dos variables:
hash = {:a => 1, :b => 2, :c => 3, :d => 4}
keyset = [:a, :c]
¿Cómo puedo obtener los siguientes dos hashes de la manera más simple posible?
hash1 = {:a => 1, :c => 3}
hash2 = {:b => 3, :d => 4}
Si el ejemplo no aclara mi objetivo, en esencia, lo que quiero es un híbrido entre #delete
y #delete_if
- #delete
devuelve el valor eliminado, mientras que #delete_if
me permite eliminarlo a granel. Preferiría una forma de eliminar a granel y devolver los valores eliminados, o algo equivalente.
¡Gracias!
¡Con Rails / Active Support puede usar el extract!
método:
hash = {:a => 1, :b => 2, :c => 3, :d => 4}
keyset = [:a, :c]
hash2 = hash.extract! *keyset
>> {:a=>1, :c=>3}
hash
>> {:b=>2, :d=>4}
Pruebe el soporte activo con Hash#slice
y / o Hash#except
. Los métodos de explosión también existen:
$ irb
>> require ''active_support/core_ext''
=> true
>> hash = {:a => 1, :b => 2, :c => 3, :d => 4}
=> {:a=>1, :d=>4, :b=>2, :c=>3}
>> keyset = [:a, :c]
=> [:a, :c]
>> remainders = hash.slice!(*keyset)
=> {:d=>4, :b=>2}
>> remainders
=> {:d=>4, :b=>2}
>> hash
=> {:a=>1, :c=>3}
Si no le molestan las dependencias externas, puede usar https://github.com/renra/split-off-ruby Luego puede hacer:
hash2 = hash.split_off!(:b, :d)
hash aún contendrá los valores originales para las claves: a y: c. Los métodos anteriores son lo suficientemente buenos, pero a veces es mejor expresar tu intención con el nombre correcto del método, creo.
hash = { a: 1, b: 2, c: 3, d: 4 }
keyset = [:a, :c]
left, right = hash.partition {|k,v| keyset.include? k }
Esto se deja a la izquierda y a la derecha como matrices de matrices; volver a hash:
left = Hash[left]
right = Hash[right]
puts "left=#{left.inspect}"
puts "right=#{right.inspect}"
new_hash = {}
keyset.each {|i| new_hash[i] = hash.delete(i)}
Eso pareció hacerlo por mí, sin requisitos adicionales