what into elemento declarar create contadores como arreglo agregar ruby

into - Ruby: ¿La forma más fácil de filtrar las teclas hash?



ruby puts hash (12)

Con Hash::select :

params = params.select { |key, value| /^choice/d+$/.match(key.to_s) }

Tengo un hash que se ve así:

params = { :irrelevant => "A String", :choice1 => "Oh look, another one", :choice2 => "Even more strings", :choice3 => "But wait", :irrelevant2 => "The last string" }

Y quiero una forma simple de rechazar todas las claves que no son choice + int. Podría ser choice1, o choice1 a choice10. Varía.

¿Cómo selecciono las teclas con solo la palabra seleccionada y un dígito o dígitos después de ellas?

Prima:

Convierta el hash en una cadena con tabulador (/ t) como delimitador. Hice esto, pero tomó varias líneas de código. Por lo general, los maestros de Rubio pueden hacerlo en una o más líneas.


En Ruby, la selección de Hash # es una opción correcta. Si trabajas con Rails, puedes usar Hash # slice y Hash # slice !. ej. (rieles 3.2.13)

h1 = {:a => 1, :b => 2, :c => 3, :d => 4} h1.slice(:a, :b) # return {:a=>1, :b=>2}, but h1 is not changed h2 = h1.slice!(:a, :b) # h1 = {:a=>1, :b=>2}, h2 = {:c => 3, :d => 4}


En cuanto a la pregunta de bonificación:

  1. Si tiene salida del método #select como este (lista de matrices de 2 elementos):

    [[:choice1, "Oh look, another one"], [:choice2, "Even more strings"], [:choice3, "But wait"]]

    entonces simplemente toma este resultado y ejecuta:

    filtered_params.join("/t") # or if you want only values instead of pairs key-value filtered_params.map(&:last).join("/t")

  2. Si tiene salida del método #delete_if como este (hash):

    {:choice1=>"Oh look, another one", :choice2=>"Even more strings", :choice3=>"But wait"}

    entonces:

    filtered_params.to_a.join("/t") # or filtered_params.values.join("/t")


Esta es una línea para resolver la pregunta original completa:

params.select { |k,_| k[/choice/]}.values.join(''/t'')

Pero la mayoría de las soluciones anteriores resuelven un caso en el que necesitas saber las claves antes de tiempo, usando slice o simple regexp.

Aquí hay otro enfoque que funciona para casos de uso simples y más complejos, que es intercambiable en tiempo de ejecución

data = {} matcher = ->(key,value) { COMPLEX LOGIC HERE } data.select(&matcher)

Ahora, no solo esto permite una lógica más compleja para hacer coincidir las claves o los valores, sino que también es más fácil de probar, y puede intercambiar la lógica correspondiente en el tiempo de ejecución.

Ex para resolver el problema original:

def some_method(hash, matcher) hash.select(&matcher).values.join(''/t'') end params = { :irrelevant => "A String", :choice1 => "Oh look, another one", :choice2 => "Even more strings", :choice3 => "But wait", :irrelevant2 => "The last string" } some_method(params, ->(k,_) { k[/choice/]}) # => "Oh look, another one//tEven more strings//tBut wait" some_method(params, ->(_,v) { v[/string/]}) # => "Even more strings//tThe last string"


La forma más fácil es incluir la gem ''activesupport'' (o gem ''active_support'' ).

Entonces, en tu clase solo necesitas

require ''active_support/core_ext/hash/slice''

y para llamar

params.slice(:choice1, :choice2, :choice3) # => {:choice1=>"Oh look, another one", :choice2=>"Even more strings", :choice3=>"But wait"}

Creo que no vale la pena declarar otras funciones que puedan tener errores, y es mejor usar un método que se haya modificado durante los últimos años.


La forma más fácil es incluir la gema ''activesupport'' (o gema ''active_support'').

params.slice(:choice1, :choice2, :choice3)


Pon esto en un inicializador

class Hash def filter(*args) return nil if args.try(:empty?) if args.size == 1 args[0] = args[0].to_s if args[0].is_a?(Symbol) self.select {|key| key.to_s.match(args.first) } else self.select {|key| args.include?(key)} end end end

Entonces puedes hacer

{a: "1", b: "b", c: "c", d: "d"}.filter(:a, :b) # => {a: "1", b: "b"}

o

{a: "1", b: "b", c: "c", d: "d"}.filter(/^a/) # => {a: "1"}


Si quieres el hash restante:

params.delete_if {|k, v| ! k.match(/choice[0-9]+/)}

o si solo quieres las llaves:

params.keys.delete_if {|k| ! k.match(/choice[0-9]+/)}


Si trabaja con rieles y tiene las claves en una lista separada, puede usar la notación * :

keys = [:foo, :bar] hash1 = {foo: 1, bar:2, baz: 3} hash2 = hash1.slice(*keys) => {foo: 1, bar:2}

Como otras respuestas indicadas, ¡también puedes usar slice! para modificar el hash en su lugar (y devolver la clave / valores borrados).


NOTA: Si está utilizando Rails, puede usar Hash.slice como lo indica lfx_cool en la respuesta a continuación.

Si está usando Ruby, puede usar el método de select . Tendrá que convertir la clave de un Símbolo a una Cadena para hacer la coincidencia de expresión regular. Esto le dará un nuevo hash con solo las opciones en él.

choices = params.select { |key, value| key.to_s.match(/^choice/d+/) }

o puede usar delete_if y modificar el Hash existente, por ej.

params.delete_if { |key, value| !key.to_s.match(/choice/d+/) }

o si solo son las claves y no los valores que desea, entonces puede hacer:

params.keys.select { |key| key.to_s.match(/^choice/d+/) }

y esto le dará a la justa una Matriz de las teclas, por ejemplo [:choice1, :choice2, :choice3]


params = { :irrelevant => "A String", :choice1 => "Oh look, another one", :choice2 => "Even more strings", :choice3 => "But wait", :irrelevant2 => "The last string" } choices = params.select { |key, value| key.to_s[/^choice/d+/] } #=> {:choice1=>"Oh look, another one", :choice2=>"Even more strings", :choice3=>"But wait"}


params.select{ |k,v| k =~ /choice/d/ }.map{ |k,v| v}.join("/t")