2010-05-21 4 views
0

J'essayais d'écrire une simple méthode d'aplatissement de tableau, mais cela ne fonctionne pas avec une variable d'instance. Cela fonctionne seulement en utilisant des variables de classe. Quelqu'un peut-il me dire pourquoi? et comment le faire fonctionner en utilisant des variables d'instance.Array Flatten ne fonctionne pas (Instance variable nil)

class Array 
@y = [] 
    def flatten_array 
    self.each do |x| 
    if x.class.to_s != 'Array' 
    @y << x 
    else 
    x.flatten_array 
    end 
    end 
    return @y 
    end 
end 


a = [1,2,3,4,5] 
b = [6,7,8] 
c = [9,10] 
a1 = [12,13,a,b,c] 
puts a1.inspect 
b1 = a1.flatten_array 
puts b1.inspect 
+0

Juste curieux: qu'essayez-vous d'accomplir? Il y a déjà un 'Array # flatten', vous savez ... –

+0

Pourquoi voulez-vous utiliser une variable d'instance au lieu d'une variable locale? –

+0

Il y a une faute de frappe pour "Instance" dans le titre. –

Répondre

1

La raison pour laquelle il ne fonctionne pas pour les variables d'instance est que x.flatten_array utilise un nouveau @y, pas celui que vous accumulez. Cependant, utiliser une instance ou une variable de classe n'est pas une bonne pratique car elle utilise effectivement une variable globale pour une fonction locale.

La procédure standard pour l'écriture d'une fonction récursive qui a besoin des variables supplémentaires est d'utiliser une fonction d'assistance:

def flatten_array 
    int_flatten(self, []) 
end 

private 
def int_flatten(a, result) 
    a.each do |elem| 
    if (elem.is_a? Array) 
     int_flatten(elem, result) 
    else 
     result << elem 
    end 
    end 
    return result 
end 

ou tout simplement être prêt à utiliser la concaténation:

def flatten_array 
    result = [] 
    each do |elem| 
    if (elem.is_a? Array) 
     result += elem.flatten_array 
    else 
     result << elem 
    end 
    end 
    return result 
end 
+0

à: Marc-André Lafortune Je voulais juste écrire mon propre array_flatten pour mieux comprendre Ruby. à: Andrew Grimm Merci d'avoir signalé la faute de frappe dans le titre. Cependant, cela n'a pas répondu à ma question. Kathy, Merci pour la réponse. Je pensais que la variable locale peut ne pas fonctionner, mais apparemment je me suis trompé. J'ai essayé vos deux extraits de code. La seconde a fonctionné et d'abord n'a pas fait. S'il vous plaît voir ci-dessous. – Nick

+0

Snippet1: la classe Array def flatten_array int_flatten (self, []) fin privée def int_flatten (a, résultat) a.each do | élém | si (elem.is_a? Array) int_flatten (élém, résultat) autre résultat << élém fin fin fin fin a = [1,2,3, [4,5,6 , [7,8,9]]] b = a.flatten_array met b.inspect sortie: [1, 2, 3, [4, 5, 6, [7, 8, 9]]] – Nick

+0

Snippet2: class Array def flatten_array résultat = [] chaque fait | si (elem.is_a? Array) résultat + = elem.flatten_array autre résultat << élém fin fin résultat de retour fin fin a = [1,2,3, [4, 5,6, [7,8,9]]] b = a.flatten_array met b.inspecter sortie: [1, 2, 3, 4, 5, 6, 7, 8, 9] – Nick

0

utilisation native Array#flatten

a = [1,2,3,4,5] 
b = [6,7,8] 
c = [9,10] 
a1 = [12,13,a,b,c] 

puts a1.inspect 
#=> [12, 13, [1, 2, 3, 4, 5], [6, 7, 8], [9, 10]] 

puts a1.flatten.inspect 
#=> [12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]