2010-05-06 5 views
5

Comment est-ce que je ferais quelque chose comme ci-dessous?Multidimensional each

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

# I want this to return: 

foo 
bar 
baz 
one 
two 
three 
+0

Faut-il une virgule après ' 'foo''? –

Répondre

2

Si vous ne voulez pas aplatir le tableau et obtenir encore la fonctionnalité désirée, vous pouvez faire quelque chose comme:

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

J'aime vraiment ça! C'est plus de ce que je demandais. – RyanScottLewis

+0

Pas de problème! Si vous voulez être plus intelligent, allez sur: http://github.com/evansenter/y - une implémentation du Y-combinator dans Ruby (note: la plupart des rubis ne sont pas optimisés pour l'appel de la queue, donc avec l'emboîtage avoir des problèmes de performance). Alors vous pouvez: 'Y ([1, [2, 3], [4, [5, 6]]]) {| recurser, liste | list.respond_to? (: each)? list.each (& récursif): puts (liste)} ' La différence n'étant aucune affectation de variable (à la 'traverser' dans l'exemple ci-dessus). :] –

2

La meilleure façon:

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

Gah! Battez-moi ... –

3

Pouvez-vous utiliser flatten?

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

flatten renverra une copie du tableau, si l'original ne sera pas modifié.
Il est également entièrement récursif, donc peu importe le nombre de matrices intra-arrays dont vous disposez.

+0

puts, si un tableau est donné, imprime chaque élément du tableau sur une ligne distincte. Par conséquent, 'a = [...]; met a.flatten' peut, si désiré, remplacer la boucle 'each'. –