Tengo un hash que se parece a esto:
params = { :irrelevant => "A String",
:choice1 => "Oh look, another one",
:choice2 => "Even more strings",
:choice3 => "But wait",
:irrelevant2 => "The last string" }
Y quiero una manera simple de rechazar todas las claves que no son choice + int. Podría ser la opción1 o la opción1 a la opción10. Varía.
¿Cómo selecciono las teclas con solo la elección de palabras y un dígito o dígitos después de ellas?
Prima:
Convierta el hash en una cadena con la pestaña (\ t) como delimitador. Hice esto, pero tomó varias líneas de código. Por lo general, los maestros rubíes pueden hacerlo en una o más líneas.
Respuestas:
Editar a la respuesta original : aunque esta es la respuesta seleccionada (al momento de este comentario) es la respuesta seleccionada, la versión original de esta respuesta está desactualizada.
Estoy agregando una actualización aquí para ayudar a otros a evitar ser desviados por esta respuesta como lo hice yo.
Como menciona la otra respuesta, Ruby> = 2.5 agregó el
Hash#slice
método que anteriormente solo estaba disponible en Rails.Ejemplo:
Fin de la edición. Lo que sigue es la respuesta original que supongo que será útil si estás en Ruby <2.5 sin Rails, aunque imagino que ese caso es bastante poco común en este momento.
Si usa Ruby, puede usar el
select
método. Tendrá que convertir la clave de un Símbolo a una Cadena para hacer la coincidencia de expresiones regulares. Esto le dará un nuevo Hash con solo las opciones que contiene.o puede usar
delete_if
y modificar el hash existente, por ejemploo si solo son las claves y no los valores que desea, puede hacer:
y esto le dará solo una matriz de teclas, por ejemplo
[:choice1, :choice2, :choice3]
fuente
.select
es.reject
, si eso hace que su código sea más idiomático.#slice
forma funciona para mí en 2.5.3 incluso sin soporte activo.En Ruby, Hash # select es una opción correcta. Si trabaja con Rails, puede usar Hash # slice y Hash # slice !. por ejemplo (rieles 3.2.13)
fuente
La forma más fácil es incluir el
gem 'activesupport'
(ogem 'active_support'
).Entonces, en tu clase solo necesitas
y llamar
Creo que no vale la pena declarar otras funciones que pueden tener errores, y es mejor usar un método que se haya modificado durante los últimos años.
fuente
La forma más fácil es incluir la gema 'soporte activo' (o gema 'soporte_activo').
params.slice(:choice1, :choice2, :choice3)
fuente
Si trabaja con rieles y tiene las claves en una lista separada, puede usar la
*
notación:Como se indicó en otras respuestas, también puede usar
slice!
para modificar el hash en su lugar (y devolver la clave / valores borrados).fuente
Esta es una línea para resolver la pregunta original completa:
Pero la mayoría de las soluciones anteriores están resolviendo un caso en el que necesita conocer las claves con anticipación, utilizando
slice
o regexp simple.Aquí hay otro enfoque que funciona para casos de uso simples y más complejos, que se puede intercambiar en tiempo de ejecución
Ahora, no solo esto permite una lógica más compleja al hacer coincidir las claves o los valores, sino que también es más fácil de probar y puede intercambiar la lógica de coincidencia en tiempo de ejecución.
Ex para resolver el problema original:
fuente
Con
Hash::select
:fuente
Si quieres el hash restante:
o si solo quieres las llaves:
fuente
Pon esto en un inicializador
Entonces puedes hacer
o
fuente
fuente
En cuanto a la pregunta extra:
Si tiene salida de un
#select
método como este (lista de matrices de 2 elementos):luego simplemente tome este resultado y ejecute:
Si tiene salida de un
#delete_if
método como este (hash):luego:
fuente
map
toma bloque como argumento. Puede crear bloques sobre la marcha, con&:method
construcción, lo que crearía un bloque{|v| v.method }
. En mi caso&:last
se invocó el argumento array (matriz de 2 elementos). Si quiere jugar con él, primero verifique qué argumento está recibiendo en el bloque (obtenga 1 argumento, ¡no lo deconstruya en múltiples argumentos!) E intente encontrar 1 método (con el que no puede encadenar métodos&:method
) que le devolvería lo que querer. Si es posible, puede usar el acceso directo, si no, entonces necesita el bloqueo completofuente
Tuve un problema similar, en mi caso la solución fue un trazador de líneas que funciona incluso si las teclas no son símbolos, pero debe tener las claves de criterios en una matriz
Otro ejemplo
fuente