Code an aufeinanderfolgenden Falten collect / select / ablehnen / each
Frage
ich mit Arrays rumspielen und Hashes ziemlich viel in Rubin und mit einigem Code am Ende des wie folgt aussieht:
sum = two_dimensional_array.select{|i|
i.collect{|j|
j.to_i
}.sum > 5
}.collect{|i|
i.collect{|j|
j ** 2
}.average
}.sum
(Lassen Sie uns alle so tun, dass die obigen Codebeispiel macht Sinn, jetzt ...)
Das Problem ist, dass, obwohl Textmate (mein Redakteur der Wahl) nimmt einfach {...}
oder do...end
Blöcke ganz einfach, es nicht herausfinden kann (was verständlich ist, da kann auch ich nicht einen „richtigen“ Weg finden, zu falten die oben), wo die obigen Blöcke beginnen und enden sie falten.
Wie würden Sie das obige Codebeispiel falten?
PS: bedenkt, dass es 2 Ebene von Falten haben könnte, I über den äußeren Consecutive-Ones nur Pflege (die Blöcke mit der i)
Lösung
Um ehrlich zu sein, dass etwas gewunden ist wahrscheinlich verwirrend Textmate so viel wie alle anderen, die es halten muss, und das schließt Sie in die Zukunft.
Wenn Sie etwas sehen, dass Rollen in einen einzigen Wert auf, es ist ein gutes Beispiel für die Verwendung von 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
Was in Ihrem Beispiel ungerade ist, ist Sie verwenden wählen Sie die volle Palette zurückzukehren, angeblich to_i umgewandelt verwenden, aber in der Tat Enumerable # wählen tut so etwas nicht, und lehnt jede stattdessen für die die Funktion nil zurück. Ich bin der Annahme, dass die keine Ihrer Werte.
Auch je nachdem, wie Ihre .average Methode implementiert ist, können Sie den inject Anruf auf Saatgut wollen mit 0,0 anstelle von 0 Gleitkommawert zu verwenden.