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.