Ceylon project

Iterable

Un oggetto iterable serve a creare una sequenza di elementi; ogni appartenente a questa tipologia di oggetti deve soddisfare l'interfaccia avente appunto nome Iterable. Ceylon ci offre due tipi di rappresentazioni:

1)
Iterable<elemento, null>
2)
Iterable<elemento, nothing>

Il primo quando iterato potrebbe non produrre alcun valore ed è abbreviato con
{X*}
Il secondo restituisce almeno un valore ed è abbreviato
{X+}

Ad esempio:

{string+} x1 = {"ciao", "mondo"}
{string+} y2 = {"hello", "world", *x1}

La seconda definizione presenta il cosiddetto spread operator (si potrebbe tradurre come operatore di propagazione) * (asterisco) in quanto estende un oggetto iterable attraverso un altro. In questo caso infatti y2, se fosse traversato attraverso i suoi elementi restituirebbe la sequenza:
"hello", "world", "ciao", "mondo".

Come appare dalla documentazione ufficiale Iterable è un sottotipo di Category il quale prevede un metodo contains per certificare l'esistenza all'interno di un elemento. A causa di questa gerarchia tale metodo è disponbile anche per gli iterable ed in particolare si fa uso dell'abbreviazione sintattica basata sulla keyword in. Di seguito vediamo un esempio riassuntivo di quanto visto finora:

  Esempio it.1
1
2
3
4
5
6
7
8
9
void hello()
{
  {String+} x1 = {"ciao", "mondo"};
  {String+} x2 = {"Hello", "World", *x1};
  if ("ciao" in x2)
  {
    print("Exist");
  }
}

Se dopo il segno di uguale l'espressione assegnata fosse {}, ovvero non fosse contenuto alcun elemento il compilatore si lamenterebbe. Per rendere legale questa scrittura, come avrete intuito, bisogna ricorrere a {String*}.
Inoltre, per quanto detto, la riga 5 poteva anche essere scritta come:

if (x2.contains("mondo"))

L'iterazione di un Iterable avviene favorevolmente usando il loop for. Modifichiamo l'esempio it.1 come segue:

  Esempio it.2
1
2
3
4
5
6
7
8
9
void hello()
{
  {String+} x1 = {"ciao", "mondo"};
  {String+} x2 = {"Hello", "World", *x1};
  for (w in x2)
  {
    print(w);
  }
}

Il nostro Iterable contiene una gran quantità di attributi e metodi che ne facilitano la manipolazione:
(nb: in qualche caso la mancanza di descrizione è dovuta al fatto che voglio vedere qualche caso pratico all'opera)

ATTRIBUTI


  nome descrizione
  coalesced  
  cycled crea una sequenza che ripete all'infinito gli item contenuti nell'iterable
empty determina se l'oggetto è vuoto, quindi una iterazione su di esso non restituisce nulla
first il primo elemento pescato da un iteratore o null se l'iterabile è vuoto
  indexed espone tutti gli elementi con un indice associato. Vedi esempio più avanti
last restituisce l'ultimo elemento o null se l'iterable è vuoto
rest restituisce un iterabile che contiene tutti gli elementi tranne il primo
sequence restituisce una sequenza che contiene tutti gli elementidell'Iterable
size restituisce il numero di elementi dell'array
string restituisce una stringa in cui ogni elemento è un elemento dell'iterable in formato stringa


  esempio INDEXED
1
2
3
4
5
void hello()
{
{String+} x1 = {"ciao", "mondo", "intero"};
print (x1.indexed);
}
 
out { 0->ciao, 1->mondo, 2->intero }

METODI

  nome descrizione
any  
by(passo) permette la selezione degli elementi basandoci su di un passo. Si veda l'esempio
chain(iterable) x1.chain(x2) restituisce una sequenza composta dai due iterable x1 e x2
collect restiuisce un iterable col risultato di una mappatura su ogni suo elemento
contains come già visto ci ci dice se un iterable contiene un certo elemento
count restituisce il numero di elementi che soddisfano un certo predicato
cycle(intero) restituisce l'iterable ripetuto tante volte quanto indicato dal parametro intero
defaultNullElements restuisce l'iterable sostituendo ogni elemento null con il valore di deafault per il tipo
every restituisce true se tutti gli elementi soddisfano un certo predicato
filter restituisce un iterable i cui elementi soddisfano un certo predicato
find trova il primo elemento che soddisfa un predicato se non esiste restituisce null
findlast trova l'ultimo elemento che soddisfa un predicato se non esiste restituisce null
fold  
following(x) stampa l'iterable in coda a x specificato. Si veda esempio
   
longerThan(n) true se l'iterable ha più elementi di n
map uguale a collect
repeat(intero) uguale a cicle
select uguale a filter
shorterThan(n) true se l'iterable ha meno elementi di quelli indicati dall'intero n.
skipping(n) Restiuisce l'iterabile eliminati i primi n elementi
skippingwhile restiuisce l'iterabile eliminati gli elementi iniziali finchè un certo predicato è true
taking(n) restituisce un iterable composto dai primi n elementi dell'iterable di partenza 
takingWhile(n) Come taking finchè un certo predicato non resituisce false

  Esempio BY
1
2
3
4
5
6
7
void hello()
{
{Integer+} x1 = {10, 12, 14, 15,16,18,22,25};
print(x1.by(1));
print(x1.by(2));
print(x1.by(3));
}
 
out [10, 12, 14, 15, 16, 18, 22, 25]
{ 10, 14, 16, 22 }
{ 10, 15, 22 }
nb: la differenza di parentesi tra la prima riga e le altre è dovuta alla implementazione interna di iterable non documentata e by(1) è un caso particolare per quella implementazione

  Esempio FOLLOWING
1
2
3
4
5
6
7
void hello()
{
{Integer+} x1 = {20,12,14,35,16,18,2,25};
{Integer+} x2 = {1,2,3};
print(x1.following(3));
print(x1.following(x2));
}