2012-01-09 8 views
6

Voglio chiamare la funzione f 5 volte (per esempio) e ottenere un elenco di risultati. In questo momento ho questo:Chiamare una funzione più volte e ottenere un elenco di risultati

(1..5).to_a.map!{f} 

Nota: In questo momento f è una funzione che prende nessun input e restituisce true o false. Quindi, quando questo viene eseguito in esecuzione, ottengo un elenco di 5 valori true/false.

C'è un modo migliore per fare questo usando altre funzioni integrate (possibilmente reduce? Ho avuto questa idea, ma non riesco a capire come usarlo ...)

risposta

31
5.times.collect { f } 

(Assumendo senza parametri. map è un alias per collect, preferisco il nome collect quando in realtà la raccolta come sembra più comunicativo, ma YMMV)

anch'io preferisco il più 5.times invece di (1..5).. Anche questo sembra più comunicativo: non sto realmente "iterando su un intervallo", sto "facendo qualcosa cinque volte".

IMO la risposta è leggermente controintuitiva in questo caso, dal momento che non sto eseguendo veramente collect cinque volte, ma collect.5.times { f } non funziona, quindi giochiamo comunque un po 'di gioco mentale.

+0

wow ... come mi è mancato! grazie @ David Newton, esattamente quello che stavo cercando. – trh178

3

Prova la forma di blocco della costruzione Array se si vuole zero argomenti sempre più basate:

Array.new(5) {|x| (x+1).to_f} # => [1.0, 2.0, 3.0, 4.0, 5.0] 
Array.new(10) { rand } # => [0.794129655156092, ..., 0.794129655156092] 
0

Si può solo accorciare il codice non mettendo to_a ... (1..5) è un enumerabile così funziona con la mappa.

(1..5).map!{f}

1

Usa Array.new con un blocco

Array.new(10) { f } 

Il valore dell'indice è disponibile se lo si desidera:

Array.new(10) { |i| f(i) } 

From the docs:

[Con ab lock], viene creata una matrice della dimensione specificata. Ogni elemento in questo array viene creato passando l'indice dell'elemento al blocco specificato e memorizzando il valore restituito.

Questo è stato possibile dal at least 1.8.7.