che avrei scritto:
(0..100).flat_map { |x| (0..100-x).map { |y| [x, y, 100-x-y] } }
#=> [[0, 0, 100], [0, 1, 99]], ..., [99, 1, 0], [100, 0, 0]]
nota Sito 1: questo è un classico esempio in cui la lista-comprensioni brillantezza (e ancora di più se ci fosse una condizione da qualche parte). Poiché Ruby non ha LC, dobbiamo eseguire la conversione tipica in OOP: N-1flat_map
's + map
. Sarebbe fantastico avere LC in Ruby (controllare this feature request), Scala ha dimostrato che anche un puro linguaggio OOP trae molto vantaggio da questo zucchero sintattico (sebbene io possa capire la prevenzione dagli sviluppatori a causa del protocollo/metodo implicito iterabile). Su un rubino immaginario che li ha sostenuti devi scrivere:
[[x, y, 100-x-y] for x in 0..100 for y in 0..100-x] # imaginary Ruby
Nota a margine 2: Immagina che si preferisce una soluzione meno dispendiosa di memoria (che probabilmente non è necessario l'intero array). Una soluzione pigra con Ruby 2.0 richiede solo di aggiungere un paio di [lazy][2]
deleghe:
(0..100).lazy.flat_map { |x| (0..100-x).lazy.map { |y| [x, y, 100-x-y] } }
Nota a margine 3: Solo per completezza, in linea di risposta @akuhn, un'altra soluzione pigra utilizzando enumeratori:
Enumerator.new do |e|
(0..100).each { |x| (0..100-x).each { |y| e.yield([x, y, 100-x-y]) } }
end
Ricordarsi di selezionare alcune delle risposte – tokland