Para agregar un nuevo par a Hash lo hago:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
¿Hay una forma similar de eliminar una clave de Hash?
Esto funciona:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
pero esperaría tener algo como:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
Es importante que el valor de retorno sea el hash restante, por lo que podría hacer cosas como:
foo(my_hash.reject! { |k| k == my_key })
en una linea
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Misha Moroshko
fuente
fuente
Respuestas:
Rails tiene una excepción / excepto! método que devuelve el hash con esas claves eliminadas. Si ya está utilizando Rails, no tiene sentido crear su propia versión de esto.
fuente
require "active_support/core_ext/hash/except"
Oneliner liso rubí, solo funciona con rubí> 1.9.x:
El método Tap siempre devuelve el objeto sobre el que se invoca ...
De lo contrario, si lo ha requerido
active_support/core_ext/hash
(que se requiere automáticamente en todas las aplicaciones de Rails), puede usar uno de los siguientes métodos según sus necesidades:excepto que utiliza un enfoque de lista negra, por lo que elimina todas las claves enumeradas como argumentos, mientras que slice utiliza un enfoque de lista blanca, por lo que elimina todas las claves que no figuran como argumentos. También existe la versión de explosión de esos métodos (
except!
yslice!
) que modifican el hash dado pero su valor de retorno es diferente, ambos devuelven un hash. Representa las claves eliminadasslice!
y las claves que se guardan paraexcept!
:fuente
h
.Hash#except
no modificará el hash original.h.dup.tap { |hs| hs.delete(:a) }
para evitar modificar el hash original.¿Por qué no solo usar:
fuente
merge
,merge!
,delete
, pero sindetele!
...foo(hash.delete(key) || hash)
delete
hizo no modificar su parámetro y sidelete!
existió y modificó su parámetro.Hay muchas formas de eliminar una clave de un hash y obtener el hash restante en Ruby.
.slice
=> Devolverá las claves seleccionadas y no las eliminará del hash original. Úseloslice!
si desea eliminar las claves permanentemente; de lo contrario, use simpleslice
..delete
=> Eliminará las claves seleccionadas del hash original (puede aceptar solo una clave y no más de una)..except
=> Devolverá las claves restantes pero no eliminará nada del hash original. Úseloexcept!
si desea eliminar las claves permanentemente; de lo contrario, use simpleexcept
..delete_if
=> En caso de que necesite eliminar una clave basada en un valor. Obviamente eliminará las claves coincidentes del hash original..compact
=> Se utiliza para eliminar todos losnil
valores del hash. Úselocompact!
si desea eliminar losnil
valores permanentemente; de lo contrario, use simplecompact
.Resultados basados en Ruby 2.2.2.
fuente
slice
yexcept
se agregan usandoActiveSupport::CoreExtensions::Hash
. No son parte del núcleo de Ruby. Pueden ser utilizados porrequire 'active_support/core_ext/hash'
Hash#slice
está en la biblioteca estándar. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice ¡Yay!Si desea usar Ruby puro (sin Rails), no desea crear métodos de extensión (tal vez solo necesite esto en uno o dos lugares y no quiera contaminar el espacio de nombres con toneladas de métodos) y no quiera edite el hash en su lugar (es decir, usted es fanático de la programación funcional como yo), puede 'seleccionar':
fuente
He configurado esto para que .remove devuelva una copia del hash con las claves eliminadas, ¡mientras que eliminar! modifica el hash mismo. Esto está de acuerdo con las convenciones de rubí. por ejemplo, desde la consola
fuente
Puedes usar
except!
desde lafacets
gema:El hash original no cambia.
EDITAR: como dice Russel, las facetas tienen algunos problemas ocultos y no son completamente compatibles con API con ActiveSupport. Por otro lado, ActiveSupport no es tan completo como las facetas. Al final, usaría AS y dejaría los casos extremos en su código.
fuente
require 'facets/hash/except'
y no hay "problemas" (no estoy seguro de qué problemas serían de todos modos que no sean 100% como API). Si está haciendo un proyecto Rails con AS tiene sentido, si no, Facets tiene una huella mucho menor.En lugar de parchear mono o incluir innecesariamente grandes bibliotecas, puede usar mejoras si está utilizando Ruby 2 :
Puede usar esta función sin afectar otras partes de su programa o tener que incluir grandes bibliotecas externas.
fuente
en puro rubí:
fuente
Ver Ruby on Rails: eliminar varias claves hash
fuente
each
devolvería la matriz.Fue genial si eliminar devuelve el par de eliminación del hash. Estoy haciendo esto:
fuente
Esta es una forma de hacerlo en una línea, pero no es muy legible. Recomienda usar dos líneas en su lugar.
fuente
Hash#except
y yaHash#except!
se han mencionado lo suficiente. LaProc.new
versión no es muy legible como mencionas y también es más complicada queuse_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Tal vez solo borre esta respuesta.Múltiples formas de eliminar Key in Hash. puedes usar cualquier método desde abajo
Hay tantas maneras, puedes mirar Ruby doc de Hash aquí .
Gracias
fuente
Esto también funcionaría:
hash[hey] = nil
fuente