Codice pieghevole su consecutivo raccolta / select / rifiutare / ogni
Domanda
I giocare con array e hash un bel po 'di rosso rubino e finire con un codice simile al seguente:
sum = two_dimensional_array.select{|i|
i.collect{|j|
j.to_i
}.sum > 5
}.collect{|i|
i.collect{|j|
j ** 2
}.average
}.sum
(Andiamo tutti finta che l'esempio di codice di cui sopra ha un senso ora ...)
Il problema è che anche se TextMate (il mio editore di scelta) raccoglie semplici blocchi {...}
o do...end
abbastanza facilmente, ma non riesco a capire (che è comprensibile dato che anche io non riesco a trovare un modo "corretto" per piegare sopra) in cui i blocchi sopra di inizio e fine piegarli.
Come si piegare l'esempio di codice di cui sopra?
PS: considerando che potrebbe avere 2 livelli di piegatura, che interessa solo quelli consecutivi esterni (i blocchi con il i)
Soluzione
Per essere onesti, qualcosa che probabilmente è contorto confusione TextMate tanto quanto chiunque altro che ha a mantenerla, e che include in futuro.
Ogni volta che vedi qualcosa che si arrotola in un singolo valore, si tratta di un buon caso per l'utilizzo di Enumerable # iniettare.
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
Cosa c'è di strano nel tuo esempio è che si sta utilizzando select per restituire la gamma completa, presumibilmente convertiti utilizzando to_i, ma in realtà enumerabili # selezionare non fa nulla di simile, e invece rifiuta ogni per il quale la funzione restituisce zero. Sto presumendo che è nessuno dei vostri valori.
Anche a seconda di come viene implementato il metodo di .average, si consiglia di seminare la chiamata iniettare con 0.0 invece di 0 a utilizzare un valore in virgola mobile.