F # - Elenchi
In F #, un elenco è una serie ordinata e immutabile di elementi dello stesso tipo. In una certa misura è equivalente a una struttura dati di un elenco collegato.
Il modulo F #, Microsoft.FSharp.Collections.List,ha le operazioni comuni sugli elenchi. Tuttavia F # importa questo modulo automaticamente e lo rende accessibile a ogni applicazione F #.
Creazione e inizializzazione di un elenco
Di seguito sono riportati i vari modi per creare elenchi:
Utilizzando list literals.
Utilizzando cons (: :) operatore.
Usando il List.init metodo del modulo List.
Usandone alcuni syntactic constructs chiamato List Comprehensions.
List Literals
In questo metodo, è sufficiente specificare una sequenza di valori delimitata da punto e virgola tra parentesi quadre. Ad esempio:
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
I contro (: :) Operator
Con questo metodo, puoi aggiungere alcuni valori anteponendo o cons-ingin un elenco esistente utilizzando l'operatore ::. Ad esempio:
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[] denota un elenco vuoto.
List init Method
Il metodo List.init del modulo List viene spesso utilizzato per creare elenchi. Questo metodo ha il tipo -
val init : int -> (int -> 'T) -> 'T list
Il primo argomento è la lunghezza desiderata del nuovo elenco e il secondo argomento è una funzione di inizializzazione, che genera elementi nell'elenco.
Per esempio,
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
Qui, la funzione index genera l'elenco.
Comprensioni dell'elenco
Le comprensioni di elenchi sono costrutti sintattici speciali utilizzati per generare elenchi.
La sintassi di comprensione dell'elenco F # è disponibile in due forme: intervalli e generatori.
Gli intervalli hanno i costrutti - [inizio .. fine] e [inizio .. passo .. fine]
Per esempio,
let list3 = [1 .. 10]
I generatori hanno il costrutto - [for x in collection do ... yield expr]
Per esempio,
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
Come la yield parola chiave inserisce un singolo valore in un elenco, la parola chiave, yield!, inserisce una raccolta di valori nell'elenco.
La seguente funzione dimostra i metodi precedenti:
Esempio
(* using list literals *)
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2
(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3
(* using range constructs *)
let list4 = ['a' .. 'm']
printfn "The list: %A" list4
(* using init method *)
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
printfn "The list: %A" list5
(* using yield operator *)
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6
(* using yield operator *)
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7
(* using yield! operator *)
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8
Quando compili ed esegui il programma, restituisce il seguente output:
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]
Proprietà del tipo di dati elenco
La tabella seguente mostra varie proprietà del tipo di dati elenco:
Proprietà | genere | Descrizione |
---|---|---|
Testa | 'T | Il primo elemento. |
Vuoto | 'T elenco | Una proprietà statica che restituisce un elenco vuoto del tipo appropriato. |
È vuoto | bool | true se l'elenco non ha elementi. |
Articolo | 'T | L'elemento all'indice specificato (in base zero). |
Lunghezza | int | Il numero di elementi. |
Coda | 'T elenco | L'elenco senza il primo elemento. |
L'esempio seguente mostra l'uso di queste proprietà:
Esempio
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
// Use of Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))
Quando compili ed esegui il programma, restituisce il seguente output:
list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4
Operatori di base in elenco
La tabella seguente mostra le operazioni di base sul tipo di dati dell'elenco:
Valore | Descrizione |
---|---|
append: 'T list →' T list → 'T list | Restituisce un nuovo elenco che contiene gli elementi del primo elenco seguito dagli elementi del secondo. |
media: lista 'T → ^ T | Restituisce la media degli elementi nell'elenco. |
averageBy: ('T → ^ U) →' T list → ^ U | Restituisce la media degli elementi generati applicando la funzione a ogni elemento della lista. |
scegli: (opzione 'T →' U) → lista 'T → lista' 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 →' U list) → 'T list →' U list | Per ogni elemento della lista, applica la funzione data. Concatena tutti i risultati e restituisce l'elenco combinato. |
concat: seq <'T list> →' T list | Restituisce un nuovo elenco che contiene gli elementi di ciascuno degli elenchi in ordine. |
vuoto: lista 'T | Restituisce un elenco vuoto del tipo specificato. |
esiste: ('T → bool) →' T list → bool | Verifica se un qualsiasi elemento della lista soddisfa il predicato dato. |
esiste2: ('T1 →' T2 → bool) → 'T1 list →' T2 list → bool | Verifica se una qualsiasi coppia di elementi corrispondenti delle liste soddisfa il predicato dato. |
filtro: ('T → bool) →' T list → 'T list | Restituisce una nuova raccolta contenente solo gli elementi della raccolta per cui restituisce il predicato specificato true. |
trova: ('T → bool) →' T list → 'T | Restituisce il primo elemento per il quale restituisce la funzione data true. |
findIndex: ('T → bool) →' T list → int | Restituisce l'indice del primo elemento nell'elenco che soddisfa il predicato dato. |
fold: ('State →' T → 'State) →' State → 'T list →' State | Applica una funzione a ciascun elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Questa funzione accetta il secondo argomento e applica la funzione ad esso e al primo elemento dell'elenco. Quindi, passa questo risultato nella funzione insieme al secondo elemento e così via. Infine, restituisce il risultato finale. Se la funzione di input è f e gli elementi sono i0 ... iN, questa funzione calcola f (... (fs i0) i1 ...) iN. |
fold2: ('State →' T1 → 'T2 →' State) → 'State →' T1 list → 'T2 list →' State | Applica una funzione agli elementi corrispondenti di due raccolte, inserendo un argomento accumulatore attraverso il calcolo. Le collezioni devono avere dimensioni identiche. Se la funzione di input è f e gli elementi sono i0 ... iN e j0 ... jN, questa funzione calcola f (... (fs i0 j0) ...) iN jN. |
foldBack: ('T →' State → 'State) →' T list → 'State →' State | Applica una funzione a ciascun elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Se la funzione di input isf e gli elementi sono i0 ... iN, calcola f i0 (... (f iN s)). |
foldBack2: ('T1 →' T2 → 'State →' State) → 'T1 list →' T2 list → 'State →' State | Applica una funzione agli elementi corrispondenti di due raccolte, inserendo un argomento accumulatore attraverso il calcolo. Le collezioni devono avere dimensioni identiche. Se la funzione di input è f e gli elementi sono i0 ... iN e j0 ... jN, questa funzione calcola f i0 j0 (... (f iN jN s)). |
forall: ('T → bool) →' T list → bool | Verifica se tutti gli elementi della raccolta soddisfano il predicato specificato. |
forall2: ('T1 →' T2 → bool) → 'T1 list →' T2 list → bool | Verifica se tutti gli elementi corrispondenti della raccolta soddisfano a coppie il predicato specificato. |
head: 'T lista →' T | Restituisce il primo elemento della lista. |
init: int → (int → 'T) →' T list | Crea un elenco chiamando il generatore specificato su ogni indice. |
isEmpty: 'T list → bool | ritorna true se l'elenco non contiene elementi, false altrimenti. |
iter: ('T → unit) →' T list → unit | Applica la funzione data a ogni elemento della raccolta. |
iter2: ('T1 →' T2 → unit) → 'T1 list →' T2 list → unit | Applica la funzione data a due raccolte contemporaneamente. Le collezioni devono avere dimensioni identiche. |
iteri: (int → 'T → unit) →' T list → unit | Applica la funzione data a ogni elemento della raccolta. L'intero passato alla funzione indica l'indice dell'elemento. |
iteri2: (int → 'T1 →' T2 → unit) → 'T1 list →' T2 list → unit | Applica la funzione data a due raccolte contemporaneamente. Le collezioni devono avere dimensioni identiche. L'intero passato alla funzione indica l'indice dell'elemento. |
lunghezza: lista 'T → int | Restituisce la lunghezza dell'elenco. |
map: ('T →' U) → 'T list →' U list | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data a ciascuno degli elementi della raccolta. |
map2: ('T1 →' T2 → 'U) →' T1 list → 'T2 list →' U list | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data agli elementi corrispondenti delle due raccolte a coppie. |
map3: ('T1 →' T2 → 'T3 →' U) → 'T1 list →' T2 list → 'T3 list →' U list | Crea una nuova raccolta i cui elementi sono il risultato dell'applicazione della funzione data agli elementi corrispondenti delle tre raccolte simultaneamente. |
mapi: (int → 'T →' U) → 'T list →' U list | 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. |
mapi2: (int → 'T1 →' T2 → 'U) →' T1 list → 'T2 list →' U list | Come List.mapi, ma mappando gli elementi corrispondenti da due elenchi di uguale lunghezza. |
max: 'T lista →' T | Restituisce il più grande di tutti gli elementi dell'elenco, confrontato utilizzando Operators.max. |
maxBy: ('T →' U) → 'T list →' T | Restituisce il più grande di tutti gli elementi dell'elenco, confrontato utilizzando Operators.max sul risultato della funzione. |
min: 'T lista →' T | Restituisce il più basso di tutti gli elementi dell'elenco, confrontato utilizzando Operators.min. |
minBy: ('T →' U) → 'T list →' T | Restituisce il più basso di tutti gli elementi dell'elenco, confrontato utilizzando Operators.min sul risultato della funzione |
nth: 'T list → int →' T | Indici nell'elenco. Il primo elemento ha indice 0. |
ofArray: 'T [] →' T list | Crea un elenco dalla matrice data. |
ofSeq: seq <'T> →' T list | Crea un nuovo elenco dall'oggetto enumerabile specificato. |
partizione: ('T → bool) →' T list * 'T list | Divide la raccolta in due raccolte, contenenti gli elementi per i quali restituisce il predicato specificato true e false rispettivamente. |
permute: (int → int) → 'T list →' T list | Restituisce un elenco con tutti gli elementi permutati secondo la permutazione specificata. |
scegli: (opzione 'T →' U) → lista 'T →' U | Applica la funzione data agli elementi successivi, restituendo il primo risultato dove la funzione ritorna Some per qualche valore. |
ridurre: ('T →' T → 'T) →' T lista → 'T | Applica una funzione a ciascun elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Questa funzione applica la funzione specificata ai primi due elementi dell'elenco. Quindi passa questo risultato alla funzione insieme al terzo elemento e così via. Infine, restituisce il risultato finale. Se la funzione di input è f e gli elementi sono i0 ... iN, questa funzione calcola f (... (f i0 i1) i2 ...) iN. |
reduceBack: ('T →' T → 'T) →' T list → 'T | Applica una funzione a ciascun elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Se la funzione di input isf e gli elementi sono i0 ... iN, questa funzione calcola f i0 (... (f iN-1 iN)). |
replicare: (int → 'T →' T lista) | Crea un elenco chiamando il generatore specificato su ogni indice. |
rev: 'T lista →' T lista | Restituisce un nuovo elenco con gli elementi in ordine inverso. |
scan: ('State →' T → 'State) →' State → 'T list →' State list | Applica una funzione a ciascun elemento della raccolta, inserendo un argomento dell'accumulatore attraverso il calcolo. Questa funzione accetta il secondo argomento e applica ad esso la funzione specificata e il primo elemento dell'elenco. Quindi, passa questo risultato alla funzione insieme al secondo elemento e così via. Infine, restituisce l'elenco dei risultati intermedi e il risultato finale. |
scanBack: ('T →' State → 'State) →' T list → 'State →' State list | Come foldBack, ma restituisce sia i risultati intermedi che quelli finali |
ordina: 'T lista →' T lista | Ordina l'elenco fornito utilizzando Operators.compare. |
sortBy: ('T →' Key) → 'T list →' T list | Ordina l'elenco fornito utilizzando i tasti forniti dalla proiezione data. Le chiavi vengono confrontate utilizzando Operators.compare. |
sortWith: ('T →' T → int) → 'T list →' T list | Ordina l'elenco fornito utilizzando la funzione di confronto data. |
somma: ^ T lista → ^ T | Restituisce la somma degli elementi nell'elenco. |
sumBy: ('T → ^ U) →' T list → ^ U | Restituisce la somma dei risultati generati applicando la funzione a ogni elemento della lista. |
coda: lista 'T → lista' T | Restituisce l'elenco di input senza il primo elemento. |
toArray: 'T list →' T [] | Crea un array dall'elenco fornito. |
toSeq: 'T list → seq <' T> | Visualizza l'elenco fornito come una sequenza. |
tryFind: ('T → bool) →' T list → 'T opzione | Restituisce il primo elemento per il quale restituisce la funzione data true. RitornoNone se tale elemento non esiste. |
tryFindIndex: ('T → bool) →' T list → int opzione | Restituisce l'indice del primo elemento nell'elenco che soddisfa il predicato dato. RitornoNone se tale elemento non esiste. |
tryPick: (opzione 'T →' U) → lista 'T → opzione' U | Applica la funzione data agli elementi successivi, restituendo il primo risultato dove la funzione ritorna Someper qualche valore. Se tale elemento non esiste, ritornaNone. |
unzip: ('T1 *' T2) list → 'T1 list *' T2 list | Divide un elenco di coppie in due elenchi. |
unzip3: ('T1 *' T2 * 'T3) list →' T1 list * 'T2 list *' T3 list | Divide un elenco di triple in tre elenchi. |
zip: 'Elenco T1 →' Elenco T2 → ('T1 *' T2) elenco | Combina i due elenchi in un elenco di coppie. Le due liste devono avere la stessa lunghezza. |
zip3: 'T1 list →' T2 list → 'T3 list → (' T1 * 'T2 *' T3) list | Combina le tre liste in una lista di triple. Gli elenchi devono avere la stessa lunghezza. |
I seguenti esempi dimostrano gli usi delle funzionalità di cui sopra:
Esempio 1
Questo programma mostra l'inversione di un elenco in modo ricorsivo:
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
let reverse lt =
let rec loop acc = function
| [] -> acc
| hd :: tl -> loop (hd :: acc) tl
loop [] lt
printfn "The reversed list: %A" (reverse list1)
Quando compili ed esegui il programma, restituisce il seguente output:
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Tuttavia, puoi utilizzare l'estensione rev funzione del modulo per lo stesso scopo -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)
Quando compili ed esegui il programma, restituisce il seguente output:
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Esempio 2
Questo programma mostra il filtraggio di un elenco utilizzando il List.filter metodo -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2
Quando compili ed esegui il programma, restituisce il seguente output:
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]
Esempio 3
Il List.map metodo mappa un elenco da un tipo a un altro -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2
Quando compili ed esegui il programma, restituisce il seguente output:
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]
Esempio 4
Il List.append metodo e l'operatore @ aggiunge un elenco a un altro -
let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2
printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3
let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2
printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3
Quando compili ed esegui il programma, restituisce il seguente output:
The first list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']
Esempio 5
Il List.sortmetodo ordina un elenco. IlList.sum fornisce la somma degli elementi nell'elenco e il metodo List.average metodo fornisce la media degli elementi nell'elenco -
let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1
let list2 = List.sort list1
printfn "The sorted list: %A" list2
let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg
Quando compili ed esegui il programma, restituisce il seguente output:
The list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857
Un'operazione di "piegatura" applica una funzione a ciascun elemento in un elenco, aggrega il risultato della funzione in una variabile accumulator e restituisce l'accumulatore come risultato dell'operazione di piegatura.
Esempio 6
Il List.fold metodo applica una funzione a ciascun elemento da sinistra a destra, mentre List.foldBack applica una funzione a ogni elemento da destra a sinistra.
let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])
Quando compili ed esegui il programma, restituisce il seguente output:
Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.