#28 in_groups_of
Di seguito è un’applicazione che mostra una lista di task. I task sono visualizzati in una tabella in un unica colonna. Potremmo fare un miglior uso dello spazio usando più colonne, ma qual è il modo migliore per farlo? Rails fornisce un metodo chiamato in_groups_of
, come estensione agli oggetti Array
, che ci aiuta nel compito.
La nostra lista di task in una singola colonna.
Per mostrare come funziona in_groups_of
, lo vedremo in azione dalla console.
>> a = (1..12).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] >> a.in_groups_of(4) => [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] >> a.in_groups_of(3) => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
Nella prima riga abbiamo creato un array di dodici elementi mediante un range. Il metodo in_groups_of
usato passando un singolo argomento (intero positivo) restituisce un array di array, ciascuno contenente n elementi, dove n è il valore del parametro attuale passato. Nel codice abbiamo diviso l’array prima in tre gruppi di quattro elementi e poi in quattro gruppi di tre elementi. (Si noti che in_groups_of
restituisce una copia dell’array originale, non lo modifica.)
Mostrare i nostri task in colonna
Ora che sappiamo come usare il metodo in_groups_of
, possiamo sfruttarlo nel codice della nostra vista per mostrare la lista dei task su più colonne. La parte significative della vista index attualmente appare così:
<table> <% @tasks.each do |task| %> <tr> <td><%= task.name %></td> </tr> <% end %> </table>
La cambiamo in questo modo:
<table> <% @tasks.in_groups_of(4) do |tasks| %> <tr> <% tasks.each do |task| %> <td><%= task.name %></td> <% end %> </tr> <% end %> </table>
Si può usare un blocco assieme al in_groups_of
, in modo tale da dividere i nostri task in gruppi di quattro elementi, stampare un tag di apertura tr
, poi iterare su ogni task del gruppo e stamparlo fra tag td
e infine chiudere il tag tr
. Il risultato è visibile qui sotto:
I nostri task sono ora mostrati su quattro colonne come volevamo, ma non è ancora abbastanza. Poichè stavamo mostrando dodici task a gruppi di quattro, abbiamo riempito tutte le colonne e le righe. Se tuttavia aggiungessimo un altro paio di task e ricaricassimo la pagina, accadrebbe la seguente cosa:
=======I nostri task sono ora mostrati su quattro colonne come volevamo, ma non è ancora abbastanza. Poichè stavamo mostrando dodici task a gruppi di quattro, abbiamo riempito tutte le colonne e le righe. Se tuttavia aggiungessimo un altro paio di task e ricaricassimo la pagina, accadrebbe la seguente cosa:
Possiamo capirne la ragione se torniamo indietro alla console e proviamo a dividere il nostro array di dodici elementi a gruppi di cinque.
>> a = (1..12).to_a >> a.in_groups_of(5) => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, nil, nil, nil]]
Se non ci sono abbastanza elementi per riempire l’ultimo array, in_groups_of
usa nil
per riempire l’ultimo gruppo. Per evitare ciò, passiamo un secondo argomento al metodo. Se il secondo argomento (booleano) passato è false
, l’ultimo array sarà più corto degli altri; se anzichè un booleano passassimo un altro valore come secondo argomento, quel valore verrebbe utilizzato per riempire (eventualmente) l’ultimo array.
>> a.in_groups_of(5, false) => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]] >> a.in_groups_of(5, 0) => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 0, 0, 0]] >>
Se dunque aggiungiamo false
come secondo argomento al nostro in_groups_of
presente in vista, la pagina verrà mostrata indipendentemente dal numero di task presenti.