2009-11-18 11 views
1

Je joue avec des tableaux et hachages beaucoup en rubis et finissent avec un code qui ressemble à ceci:Code de pliage sur consécutifs Collect/select/rejeter/chaque

sum = two_dimensional_array.select{|i| 
    i.collect{|j| 
    j.to_i 
    }.sum > 5 
}.collect{|i| 
    i.collect{|j| 
    j ** 2 
    }.average 
}.sum 

(Nous allons tous faire semblant que la Le problème est que même si TextMate (l'éditeur de mon choix) récupère assez facilement les blocs {...} ou do...end, il ne peut pas le comprendre (ce qui est compréhensible puisque même ne peut pas trouver un moyen "correct" de plier ce qui précède) où les blocs ci-dessus commencent et finissent de les plier.

Comment plieriez-vous l'exemple de code ci-dessus?

PS: considérant qu'il pourrait avoir 2 niveaux de pliage, je ne se soucient que ceux consécutifs externes (les blocs avec le i)

Répondre

1

Pour être honnête, ce que TextMate alambiqué est source de confusion probablement autant que tout le monde d'autre qui doit le maintenir, et cela vous inclut dans le futur.

Chaque fois que vous voyez quelque chose qui se transforme en une seule valeur, c'est un bon exemple pour utiliser Enumerable # inject.

sum = two_dimensional_array.inject(0) do |sum, row| 
    # Convert row to Fixnum equivalent 
    row_i = row.collect { |i| i.to_i } 

    if (row_i.sum > 5) 
    sum += row_i.collect { |i| i ** 2 }.average 
    end 

    sum # Carry through to next inject call 
end 

Ce qui est étrange dans votre exemple est que vous utilisez sélectionnez pour retourner un tableau complet, aurait été converti en utilisant to_i, mais en fait Enumerable # select ne pas une telle chose, et rejette la place tout pour laquelle la fonction renvoie nil . Je présume que ce n'est pas vos valeurs. En outre, en fonction de la mise en œuvre de votre méthode .average, vous pouvez amorcer l'appel d'injection avec 0.0 au lieu de 0 pour utiliser une valeur à virgule flottante.

+0

Le code que j'ai posté est quelque chose que j'ai écrit sans vraiment le regarder, je voulais juste lui donner l'aspect approximatif d'une grande partie du code que j'écris (/ moi tourne select -> collect). Je vais regarder dans injecter et si cela m'aide à simplifier les choses. – Kostas