2010-05-06 7 views
5

¿Cómo haré algo como a continuación?Multidimensional cada

[ 
    'foo' 
    ['bar', 'baz'], 
    [ 
     'one', 
     ['two', 'three'] 
    ] 
].each { |word| puts word } 

# I want this to return: 

foo 
bar 
baz 
one 
two 
three 
+0

¿Debería haber una coma después de ' 'foo''? –

Respuesta

2

Si no desea para aplanar la matriz y aún así lograr la funcionalidad deseada, se puede hacer algo como:

irb(main):016:0> array = [1, [2, 3], [4, [5, 6]]] 
=> [1, [2, 3], [4, [5, 6]]] 
irb(main):017:0> (traverser = lambda { |list| list.respond_to?(:each) ? list.each(&traverser) : puts(list) })[array] 
1 
2 
3 
4 
5 
6 
=> [1, [2, 3], [4, [5, 6]]] 
+0

¡Me gusta mucho esto! Esto es más de lo que estaba pidiendo. – RyanScottLewis

+0

¡Ningún problema! Si quieres ser más inteligente, consulta: http://github.com/evansenter/y - una implementación del Y-combinator en Ruby (nota: la mayoría de los rubíes no son optimizados para la cola, por lo que con la anidación profunda esto puede tener problemas de rendimiento). Luego puede: 'S ([1, [2, 3], [4, [5, 6]]]) {| recursor, lista | list.respond_to? (: each)? list.each (& recurser): puts (list)} ' La diferencia es que no hay asignación de variable (a la 'travelling' en el ejemplo anterior). :] –

2

La forma más sencilla:

words = ['foo',['bar', 'baz'],['one',['two', 'three']]] 
words.flatten.each{ |word| puts word } 
+0

Gah! Muéstremelo ... –

3

Podría utilizar flatten?

[ 
    'foo' 
    ['bar', 'baz'], 
    [ 
     'one', 
     ['two', 'three'] 
    ] 
].flatten.each { |word| puts word } 

flatten devolverá una copia de la matriz, por lo que no se modificará el original.
También es totalmente recursivo, por lo que no importa cuántas matrices dentro de las matrices tenga.

+0

pone, si se le da una matriz, imprimirá cada elemento de la matriz en una línea separada. Por lo tanto, 'a = [...]; pone a .flatten' puede, si lo desea, reemplace el bucle 'each'. –