Iterare Sequenze

Vedi tutte le pagine e le modifiche recenti o scarica i sorgenti nella pagina


Puo’ capitare di dover effettuare un’iterazione su piu’ elementi per volta in una sequenza.

Ad esempio, per creare una galleria di immagini, avrebbe senso avere accesso contemporaneamente sia ad un elemento i che agli elementi i+1 e i-1, per poter creare dei link tipo “< prev” e “next >

In un linguaggio C-like si userebbe l’indice i esplicitamente, ma come gestire questo in un linguaggio dove l’iterazione √® implicita? Un metodo sarebbe quello di usare una variabile esterna al ciclo:

 >> count=0
 => 0
 >> ary= [1,2,3,4,5,6,7,8]
 => [1, 2, 3, 4, 5, 6, 7, 8]
 >> for i in ary
 >>  print ary[count-1],i,ary[count+1],"\n" 
 >>  count+=1
 >> end
 812
 123
 234
 345
 456
 567
 678
 78nil
 => [1, 2, 3, 4, 5, 6, 7, 8]

Questo metodo √® poco elegante ed inconsistente, ad esempio nel primo ciclo dovremmo controllare che si tratti del primo, per non usare un elemento con indice minore di zero, e nell’ultimo per non usarne uno fuori dall’Array. Ma ruby non e’ un linguaggio inconsistente ed inelegante, dunque vediamo come miglirare un po’ la cosa.

Anzitutto, possiamo usare each_with_index(), e liberarci di quella brutta variabile esterna:

 >> ary.each_with_index do |el,i|
 ?>  print ary[i-1],el,ary[i+1],"\n" 
 >> end
 812
 123
 234
 345
 456
 567
 678
 78nil
 => [1, 2, 3, 4, 5, 6, 7, 8]

Leggermente meglio, na ancora abbiamo il problema di controllare il ciclo iniziale e finale.. Sarebbe meglio se potessimo dire a ruby: “dammi n elementi consecutivi”. In effetti, possiamo farlo, usando il modulo enumerator, incluso nella libreria standard:

 >> require 'enumerator'
 => true
 >> ary.each_cons(3) do |pre,el,suc|
 ?>   print pre,el,suc,"\n" 
 >> end
 123
 234
 345
 456
 567
 678
 => nil

Perfetto! Ma cosa e’ successo ? Semplice, enumerator aggiunge alcuni metodi utili al modulo Enumerable e di conseguenza alla classe Array. Tra questi metodi esiste il comodissimo each_cons( ) che richiama il blocco ogni volta con una sequenza di n elementi, in questo caso n=3.

Nessun bisogno di gestire casi particolari o di scrivere codice brutto ed error prone, abbiamo tutto gia’ pronto.

Updated on November 26, 2005 13:26 by Ruby Fan (151.37.150.7)