Ruby Hash a una matriz de valores

118

Tengo esto:

hash  = { "a"=>["a", "b", "c"], "b"=>["b", "c"] } 

y quiero llegar a esto: [["a","b","c"],["b","c"]]

Esto parece que debería funcionar, pero no es así:

hash.each{|key,value| value}
=> {"a"=>["a", "b", "c"], "b"=>["b", "c"]} 

¿Alguna sugerencia?

tbrooke
fuente
Las respuestas a continuación son correctas ( hash.valuessiendo la mejor en mi opinión). Pero quería señalar que cuando le proporcionas un bloque Hash#each, solo devolverá el valor completo del hash. Si desea realizar una operación en cada elemento y devolverlo como una matriz, use Hash#collecto su alias Hash#map. Más cosas sobre Enumerables aquí .
brymck
3
Esta pregunta parece extrañamente familiar ... Me pregunto cuántas personas están trabajando en la misma tarea en este momento.
Peter Brown

Respuestas:

260

Además, un poco más simple ...

>> hash = { "a"=>["a", "b", "c"], "b"=>["b", "c"] }
=> {"a"=>["a", "b", "c"], "b"=>["b", "c"]}
>> hash.values
=> [["a", "b", "c"], ["b", "c"]]

Ruby doc aquí

Ray Toal
fuente
3
+! ¡Hábil! Voy a votar a pesar de tener una respuesta competitiva (uso map), ¡porque me gusta mucho esto!
Michael Durrant
2
Hash#valuesno solo es más simple, sino más eficiente. Comparar time ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.values'contime ruby -e '(1..1000000).reduce({}){|h,i| h.store i,i; h}.map{|k,v| v}'
jordanbtucker
+1 (Deslumbrado increíblemente después de que probé su código) Pasé un día sin suerte eliminando el índice usando muchos métodos ... Todo lo que puedo decir muchas gracias !!! : D
Romanos 8.38-39
2
¿Están impresas las claves en el orden exacto en que aparecen?
stack1
43

Yo usaría:

hash.map { |key, value| value }
Michael Durrant
fuente
3
No lo rechacé, pero es un equivalente más complicado a Hash#values.
Mark Thomas
1
Sí, también voté a favor de la respuesta de Ray. Me complace votar a favor de una respuesta competitiva cuando también me gusta.
Michael Durrant
3
Creo que aquí no estamos compitiendo, sino ayudándonos, ¿verdad? :)
witkacy26
Exactamente lo que estaba buscando al intentar crear una matriz a partir de un hash usando sus claves como valores. Gracias :)
Fabian Leutgeb
Útil cuando también necesitas hacer algo de lógica con las teclas al mismo tiempo.
Chris Cirefice
23
hash.collect { |k, v| v }
#returns [["a", "b", "c"], ["b", "c"]] 

Enumerable#collecttoma un bloque y devuelve una matriz de los resultados de ejecutar el bloque una vez en cada elemento del enumerable. Entonces, este código simplemente ignora las claves y devuelve una matriz de todos los valores.

El Enumerablemódulo es bastante impresionante. Conocerlo bien puede ahorrarle mucho tiempo y mucho código.

jergason
fuente
2
No olvide que, como la respuesta de @Ray Toal, hash.valueses en última instancia la respuesta correcta aquí.
tadman
O hash.map(&:second):)
Jaap Haagmans
4

Es tan simple como

hash.values
#=> [["a", "b", "c"], ["b", "c"]]

esto devolverá una nueva matriz poblada con los valores de hash

si quieres almacenar esa nueva matriz, haz

array_of_values = hash.values
#=> [["a", "b", "c"], ["b", "c"]]

array_of_values
 #=> [["a", "b", "c"], ["b", "c"]]
Melissa Quintero
fuente
2

También está este:

hash = { foo: "bar", baz: "qux" }
hash.map(&:last) #=> ["bar", "qux"]

Por qué funciona:

La &llama to_procen el objeto, y pasa como un bloque para el método.

something {|i| i.foo }
something(&:foo)
karlingen
fuente
Una explicación más detallada brianstorti.com/understanding-ruby-idiom-map-with-symbol
Sylvain