F # - Sequenze
Le sequenze, come gli elenchi, rappresentano anche una raccolta ordinata di valori. Tuttavia, gli elementi in una sequenza o un'espressione di sequenza vengono calcolati quando richiesto. Non vengono calcolati contemporaneamente e per questo motivo vengono utilizzati per rappresentare strutture dati infinite.
Definizione di sequenze
Le sequenze vengono definite utilizzando la seguente sintassi:
seq { expr }
Per esempio,
let seq1 = seq { 1 .. 10 }
Creazione di sequenze ed espressioni di sequenze
Analogamente agli elenchi, puoi creare sequenze utilizzando intervalli e comprensioni.
Le espressioni di sequenza sono le espressioni che puoi scrivere per creare sequenze. Questi possono essere fatti -
- Specificando l'intervallo.
- Specificando l'intervallo con incremento o decremento.
- Utilizzando il yield parola chiave per produrre valori che diventano parte della sequenza.
- Utilizzando l'operatore →.
I seguenti esempi dimostrano il concetto:
Esempio 1
(* Sequences *)
let seq1 = seq { 1 .. 10 }
(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }
(* descending order and decrement*)
printfn "The Sequence: %A" seq2
let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3
(* using yield *)
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4
Quando compili ed esegui il programma, restituisce il seguente output:
The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]
Esempio 2
Il seguente programma stampa i numeri primi da 1 a 50 -
(* Recursive isprime function. *)
let isprime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 1))
check 2
let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
printfn "%d" x
Quando compili ed esegui il programma, restituisce il seguente output:
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
Operazioni di base sulla sequenza
La tabella seguente mostra le operazioni di base sul tipo di dati della sequenza:
Valore | Descrizione |
---|---|
aggiungi: seq <'T> → seq <' T> → seq <'T> | Avvolge le due enumerazioni date come un'unica enumerazione concatenata. |
media: seq <^ T> → ^ T | Restituisce la media degli elementi nella sequenza. |
averageBy: ('T → ^ U) → seq <' T> → ^ U | Restituisce la media dei risultati generati applicando la funzione a ogni elemento della sequenza. |
cache: seq <'T> → seq <' T> | Restituisce una sequenza che corrisponde a una versione memorizzata nella cache della sequenza di input. |
cast: IEnumerable → seq <'T> | Avvolge un sistema a bassa tipizzazione. Sequenza di raccolte come sequenza digitata. |
scegli: (opzione 'T →' U) → seq <'T> → seq <' U> | Applica la funzione data a ogni elemento dell'elenco. Restituisce l'elenco composto dai risultati per ogni elemento in cui restituisce la funzioneSome. |
collect: ('T →' Collection) → seq <'T> → seq <' U> | Applica la funzione data a ciascun elemento della sequenza e concatena tutti i risultati. |
compareCon: ('T →' T → int) → seq <'T> → seq <' T> → int | Confronta due sequenze utilizzando la funzione di confronto data, elemento per elemento. |
concat: seq <'Collection> → seq <' T> | Combina l'enumerazione di enumerazioni data come una singola enumerazione concatenata. |
countBy: ('T →' Key) → seq <'T> → seq <' Key * int> | Applica una funzione di generazione di chiavi a ogni elemento di una sequenza e restituisce una sequenza che fornisce chiavi univoche e il loro numero di occorrenze nella sequenza originale. |
ritardo: (unità → seq <'T>) → seq <' T> | Restituisce una sequenza costruita dalla specifica ritardata data di una sequenza. |
distinto: seq <'T> → seq <' T> | Restituisce una sequenza che non contiene voci duplicate in base a hash generici e confronti di uguaglianza sulle voci. Se un elemento si verifica più volte nella sequenza, le occorrenze successive vengono eliminate. |
distintoBy: ('T →' Key) → seq <'T> → seq <' T> | Restituisce una sequenza che non contiene voci duplicate in base all'hash generico e ai confronti di uguaglianza sulle chiavi restituite dalla funzione di generazione della chiave specificata. Se un elemento si verifica più volte nella sequenza, le occorrenze successive vengono eliminate. |
vuoto: seq <'T> | Crea una sequenza vuota. |
esattamente Uno: seq <'T> →' T | Restituisce l'unico elemento della sequenza. |
esiste: ('T → bool) → seq <' T> → bool | Verifica se qualsiasi elemento della sequenza soddisfa il predicato dato. |
esiste2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool | Verifica se una coppia di elementi corrispondenti delle sequenze di input soddisfa il predicato dato. |
filtro: ('T → bool) → seq <' T> → seq <'T> | Restituisce una nuova raccolta contenente solo gli elementi della raccolta per cui restituisce il predicato specificato true. |
trova: ('T → bool) → seq <' T> → 'T | Restituisce il primo elemento per il quale restituisce la funzione data true. |
findIndex: ('T → bool) → seq <' T> → int | Restituisce l'indice del primo elemento per il quale restituisce la funzione data true. |
fold: ('State →' T → 'State) →' State → seq <'T> →' State | Applica una funzione a ogni elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Se la funzione di input è f e gli elementi sono i0 ... iN, questa funzione calcola f (... (fs i0) ...) iN. |
forall: ('T → bool) → seq <' T> → bool | Verifica se tutti gli elementi della sequenza soddisfano il predicato dato. |
forall2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool | Verifica che tutte le coppie di elementi estratti dalle due sequenze soddisfino il predicato dato. Se una sequenza è più breve dell'altra, gli elementi rimanenti della sequenza più lunga vengono ignorati. |
groupBy: ('T →' Key) → seq <'T> → seq <' Key * seq <'T >> | Applica una funzione di generazione di chiavi a ogni elemento di una sequenza e produce una sequenza di chiavi univoche. Ogni chiave univoca contiene anche una sequenza di tutti gli elementi che corrispondono a questa chiave. |
head: seq <'T> →' T | Restituisce il primo elemento della sequenza. |
init: int → (int → 'T) → seq <' T> | Genera una nuova sequenza che, una volta iterata, restituisce elementi successivi chiamando la funzione data, fino al conteggio dato. I risultati della chiamata della funzione non vengono salvati, ovvero la funzione viene riapplicata se necessario per rigenerare gli elementi. Alla funzione viene passato l'indice dell'elemento generato. |
initInfinite: (int → 'T) → seq <' T> | Genera una nuova sequenza che, una volta iterata, restituirà elementi successivi chiamando la funzione data. I risultati della chiamata della funzione non vengono salvati, ovvero la funzione verrà riapplicata se necessario per rigenerare gli elementi. Alla funzione viene passato l'indice dell'elemento generato. |
isEmpty: seq <'T> → bool | Verifica se una sequenza contiene elementi. |
iter: ('T → unit) → seq <' T> → unit | Applica la funzione data a ogni elemento della raccolta. |
iter2: ('T1 →' T2 → unit) → seq <'T1> → seq <' T2> → unit | Applica la funzione data a due raccolte contemporaneamente. Se una sequenza è più breve dell'altra, gli elementi rimanenti della sequenza più lunga vengono ignorati. |
iteri: (int → 'T → unit) → seq <' T> → unit | Applica la funzione data a ogni elemento della raccolta. L'intero passato alla funzione indica l'indice dell'elemento. |
ultimo: seq <'T> →' T | Restituisce l'ultimo elemento della sequenza. |
lunghezza: seq <'T> → int | Restituisce la lunghezza della sequenza. |
mappa: ('T →' U) → seq <'T> → seq <' U> | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data a ciascuno degli elementi della raccolta. La funzione data verrà applicata quando gli elementi vengono richiesti utilizzando il metodo MoveNext sugli enumeratori recuperati dall'oggetto. |
map2: ('T1 →' T2 → 'U) → seq <' T1> → seq <'T2> → seq <' U> | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data alle coppie di elementi corrispondenti dalle due sequenze. Se una sequenza di input è più breve dell'altra, gli elementi rimanenti della sequenza più lunga vengono ignorati. |
mapi: (int → 'T →' U) → seq <'T> → seq <' U> | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data a ciascuno degli elementi della raccolta. L'indice intero passato alla funzione indica l'indice (da 0) dell'elemento trasformato. |
max: seq <'T> →' T | Restituisce il più grande di tutti gli elementi della sequenza, confrontato utilizzando Operators.max. |
maxBy: ('T →' U) → seq <'T> →' T | Restituisce il più grande di tutti gli elementi della sequenza, confrontato utilizzando Operators.max sul risultato della funzione. |
min: seq <'T> →' T | Restituisce il più basso di tutti gli elementi della sequenza, confrontato utilizzando Operators.min. |
minBy: ('T →' U) → seq <'T> →' T | Restituisce il più basso di tutti gli elementi della sequenza, confrontato utilizzando Operators.min sul risultato della funzione. |
ennesimo: int → seq <'T> →' T | Calcola l' ennesimo elemento nella raccolta. |
ofArray: 'T array → seq <' T> | Visualizza l'array dato come una sequenza. |
ofList: 'T list → seq <' T> | Visualizza l'elenco fornito come una sequenza. |
a coppie: seq <'T> → seq <' T * 'T> | Restituisce una sequenza di ogni elemento nella sequenza di input e del suo predecessore, ad eccezione del primo elemento che viene restituito solo come predecessore del secondo elemento. |
scegli: (opzione 'T →' U) → seq <'T> →' U | Applica la funzione data a elementi successivi, restituendo il primo valore in cui la funzione restituisce a Some valore. |
sola lettura: seq <'T> → seq <' T> | Crea un nuovo oggetto sequenza che delega all'oggetto sequenza specificato. Ciò garantisce che la sequenza originale non possa essere riscoperta e modificata da un cast di tipo. Ad esempio, se viene fornito un array, la sequenza restituita restituirà gli elementi dell'array, ma non è possibile eseguire il cast dell'oggetto sequenza restituito su un array. |
ridurre: ('T →' T → 'T) → seq <' T> → 'T | Applica una funzione a ogni elemento della sequenza, inserendo un argomento dell'accumulatore attraverso il calcolo. Inizia applicando la funzione ai primi due elementi. Quindi inserisci questo risultato nella funzione insieme al terzo elemento e così via. Restituisci il risultato finale. |
scansione: ('State →' T → 'State) →' State → seq <'T> → seq <' State> | Come Seq. Piega, ma calcola su richiesta e restituisce la sequenza dei risultati intermedi e finali. |
singleton: 'T → seq <' T> | Restituisce una sequenza che produce un solo elemento. |
salta: int → seq <'T> → seq <' T> | Restituisce una sequenza che salta un numero specificato di elementi della sequenza sottostante e quindi restituisce gli elementi rimanenti della sequenza. |
skipWhile: ('T → bool) → seq <' T> → seq <'T> | Restituisce una sequenza che, quando iterata, salta gli elementi della sequenza sottostante mentre il predicato dato ritorna true, e quindi restituisce gli elementi rimanenti della sequenza. |
ordina: seq <'T> → seq <' T> | Restituisce una sequenza ordinata per chiavi. |
sortBy: ('T →' Key) → seq <'T> → seq <' T> | Applica una funzione di generazione di chiavi a ogni elemento di una sequenza e produce una sequenza ordinata per chiavi. Le chiavi vengono confrontate utilizzando il confronto generico implementato da Operators.compare. |
somma: seq <^ T> → ^ T | Restituisce la somma degli elementi nella sequenza. |
sumBy | Restituisce la somma dei risultati generati applicando la funzione a ogni elemento della sequenza. |
prendere: int → seq <'T> → seq <' T> | Restituisce i primi elementi della sequenza fino a un conteggio specificato. |
takeWhile: ('T → bool) → seq <' T> → seq <'T> | Restituisce una sequenza che, quando iterata, restituisce elementi della sequenza sottostante mentre il predicato dato ritorna true, e quindi non restituisce ulteriori elementi. |
toArray: seq <'T> →' T [] | Crea un array dalla raccolta data. |
toList: seq <'T> →' T list | Crea un elenco dalla raccolta data. |
troncare: int → seq <'T> → seq <' T> | Restituisce una sequenza che, se enumerata, non restituisce più di un numero specificato di elementi. |
tryFind: ('T → bool) → seq <' T> → 'T opzione | Restituisce il primo elemento per il quale restituisce la funzione data true, o None se tale elemento non esiste. |
tryFindIndex: ('T → bool) → seq <' T> → int opzione | Restituisce l'indice del primo elemento nella sequenza che soddisfa il predicato dato, o None se tale elemento non esiste. |
tryPick: (opzione 'T →' U) → seq <'T> → opzione' U | Applica la funzione data a elementi successivi, restituendo il primo valore in cui la funzione restituisce a Some valore. |
unfold: ('State →' T * 'State opzione) →' State → seq <'T> | Restituisce una sequenza che contiene gli elementi generati dal dato calcolo. |
dove: ('T → bool) → seq <' T> → seq <'T> | Restituisce una nuova raccolta contenente solo gli elementi della raccolta per cui restituisce il predicato specificato true. Un sinonimo di Seq.filter. |
windowed: int → seq <'T> → seq <' T []> | Restituisce una sequenza che produce finestre scorrevoli di elementi contenenti disegnati dalla sequenza di input. Ogni finestra viene restituita come un nuovo array. |
zip: seq <'T1> → seq <' T2> → seq <'T1 *' T2> | Combina le due sequenze in un elenco di coppie. Non è necessario che le due sequenze abbiano la stessa lunghezza: quando una sequenza è esaurita, tutti gli elementi rimanenti nell'altra sequenza vengono ignorati. |
zip3: seq <'T1> → seq <' T2> → seq <'T3> → seq <' T1 * 'T2 *' T3> | Combina le tre sequenze in un elenco di triple. Non è necessario che le sequenze abbiano la stessa lunghezza: quando una sequenza è esaurita, tutti gli elementi rimanenti nelle altre sequenze vengono ignorati. |
I seguenti esempi dimostrano gli usi di alcune delle funzionalità di cui sopra:
Esempio 1
Questo programma crea una sequenza vuota e la riempie in seguito -
(* Creating sequences *)
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20
printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"
let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""
(* converting an array to sequence by using cast *)
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""
(* converting an array to sequence by using Seq.ofArray *)
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""
Quando compili ed esegui il programma, restituisce il seguente output:
The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20
Si prega di notare che -
Il metodo Seq.empty crea una sequenza vuota.
Il metodo Seq.singleton crea una sequenza di un solo elemento specificato.
Il metodo Seq.init crea una sequenza per la quale vengono creati gli elementi utilizzando una determinata funzione.
I metodi Seq.ofArray e Seq.ofList <'T> creano sequenze da array ed elenchi.
Il metodo Seq.iter consente di iterare attraverso una sequenza.
Esempio 2
Il metodo Seq.unfold genera una sequenza da una funzione di calcolo che assume uno stato e lo trasforma per produrre ogni elemento successivo nella sequenza.
La seguente funzione produce i primi 20 numeri naturali:
let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "
Quando compili ed esegui il programma, restituisce il seguente output:
The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Esempio 3
Il metodo Seq.truncate crea una sequenza da un'altra sequenza, ma limita la sequenza a un numero di elementi specificato.
Il metodo Seq.take crea una nuova sequenza che contiene un numero specificato di elementi dall'inizio di una sequenza.
let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq
printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""
printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""
printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""
Quando compili ed esegui il programma, restituisce il seguente output:
The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15