F # - Listes

En F #, une liste est une série ordonnée et immuable d'éléments du même type. Il est dans une certaine mesure équivalent à une structure de données de liste chaînée.

Le module F #, Microsoft.FSharp.Collections.List,a les opérations communes sur les listes. Cependant F # importe ce module automatiquement et le rend accessible à toutes les applications F #.

Créer et initialiser une liste

Voici les différentes façons de créer des listes -

  • Utilisation de la liste literals.

  • En utilisant cons (: :) opérateur.

  • En utilisant le List.init méthode du module Liste.

  • En utilisant certains syntactic constructs appelé List Comprehensions.

Lister les littéraux

Dans cette méthode, vous spécifiez simplement une séquence de valeurs délimitée par des points-virgules entre crochets. Par exemple -

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

Les inconvénients (: :) Opérateur

Avec cette méthode, vous pouvez ajouter des valeurs en ajoutant ou en ajoutant cons-ingà une liste existante en utilisant l'opérateur ::. Par exemple -

let list2 = 1::2::3::4::5::6::7::8::9::10::[];;

[] désigne une liste vide.

List init, méthode

La méthode List.init du module List est souvent utilisée pour créer des listes. Cette méthode a le type -

val init : int -> (int -> 'T) -> 'T list

Le premier argument est la longueur souhaitée de la nouvelle liste et le second argument est une fonction d'initialisation, qui génère des éléments dans la liste.

Par exemple,

let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))

Ici, la fonction d'index génère la liste.

Compréhensions de la liste

Les compréhensions de listes sont des constructions syntaxiques spéciales utilisées pour générer des listes.

La syntaxe de compréhension de liste F # se présente sous deux formes: les plages et les générateurs.

Les plages ont les constructions - [début .. fin] et [début .. étape .. fin]

Par exemple,

let list3 = [1 .. 10]

Les générateurs ont la construction - [for x in collection do ... yield expr]

Par exemple,

let list6 = [ for a in 1 .. 10 do yield (a * a) ]

Comme le yield mot-clé pousse une seule valeur dans une liste, le mot-clé, yield!, pousse une collection de valeurs dans la liste.

La fonction suivante illustre les méthodes ci-dessus -

Exemple

(* 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

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

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]

Propriétés du type de données de liste

Le tableau suivant présente diverses propriétés du type de données de liste -

Propriété Type La description
Tête 'T Le premier élément.
Vide 'T liste Une propriété statique qui renvoie une liste vide du type approprié.
Est vide booléen true si la liste ne contient aucun élément.
Article 'T L'élément à l'index spécifié (base zéro).
Longueur int Le nombre d'éléments.
Queue 'T liste La liste sans le premier élément.

L'exemple suivant montre l'utilisation de ces propriétés -

Exemple

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))

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

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

Opérateurs de base sur la liste

Le tableau suivant montre les opérations de base sur le type de données de liste -

Valeur La description
ajouter: 'T liste →' T liste → 'T liste Renvoie une nouvelle liste qui contient les éléments de la première liste suivis des éléments de la seconde.
moyenne: 'T liste → ^ T Renvoie la moyenne des éléments de la liste.
averageBy: ('T → ^ U) →' T liste → ^ U Renvoie la moyenne des éléments générés en appliquant la fonction à chaque élément de la liste.
choisissez: ('T →' U option) → 'T list →' U list Applique la fonction donnée à chaque élément de la liste. Renvoie la liste composée des résultats pour chaque élément où la fonction retourneSome.
collecter: ('T →' U liste) → 'T liste →' U liste Pour chaque élément de la liste, applique la fonction donnée. Concatène tous les résultats et renvoie la liste combinée.
concat: seq <'T liste> →' T liste Renvoie une nouvelle liste qui contient les éléments de chacune des listes dans l'ordre.
vide: 'T liste Renvoie une liste vide du type donné.
existe: ('T → bool) →' T liste → bool Teste si un élément de la liste satisfait le prédicat donné.
existe2: ('T1 →' T2 → booléen) → 'T1 liste →' T2 liste → booléen Teste si une paire d'éléments correspondants des listes satisfait le prédicat donné.
filtre: ('T → booléen) →' T liste → 'T liste Renvoie une nouvelle collection contenant uniquement les éléments de la collection pour lesquels le prédicat donné retourne true.
trouver: ('T → booléen) →' T liste → 'T Renvoie le premier élément pour lequel la fonction donnée renvoie true.
findIndex: ('T → booléen) →' T liste → int Renvoie l'index du premier élément de la liste qui satisfait le prédicat donné.
fold: ('State →' T → 'State) →' State → 'T list →' State Applique une fonction à chaque élément de la collection, en enfilant un argument d'accumulateur dans le calcul. Cette fonction prend le deuxième argument et lui applique la fonction ainsi que le premier élément de la liste. Ensuite, il transmet ce résultat à la fonction avec le deuxième élément, et ainsi de suite. Enfin, il renvoie le résultat final. Si la fonction d'entrée est f et les éléments sont i0 ... iN, alors cette fonction calcule f (... (fs i0) i1 ...) iN.
fold2: ('State →' T1 → 'T2 →' State) → 'State →' T1 list → 'T2 list →' State Applique une fonction aux éléments correspondants de deux collections, en enfilant un argument d'accumulateur dans le calcul. Les collections doivent avoir des tailles identiques. Si la fonction d'entrée est f et les éléments sont i0 ... iN et j0 ... jN, alors cette fonction calcule f (... (fs i0 j0) ...) iN jN.
foldBack: ('T →' State → 'State) →' T list → 'State →' State Applique une fonction à chaque élément de la collection, en enfilant un argument d'accumulateur dans le calcul. Si la fonction d'entrée estf et les éléments sont i0 ... iN alors calcule f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'State →' State) → 'T1 list →' T2 list → 'State →' State Applique une fonction aux éléments correspondants de deux collections, en enfilant un argument d'accumulateur dans le calcul. Les collections doivent avoir des tailles identiques. Si la fonction d'entrée est f et les éléments sont i0 ... iN et j0 ... jN, alors cette fonction calcule f i0 j0 (... (f iN jN s)).
forall: ('T → bool) →' T liste → bool Teste si tous les éléments de la collection satisfont au prédicat donné.
forall2: ('T1 →' T2 → booléen) → 'T1 list →' T2 list → bool Teste si tous les éléments correspondants de la collection satisfont le prédicat donné par paires.
head: 'T liste →' T Renvoie le premier élément de la liste.
init: int → (int → 'T) →' T liste Crée une liste en appelant le générateur donné sur chaque index.
isEmpty: 'T liste → booléen Retour true si la liste ne contient aucun élément, false autrement.
iter: ('T → unité) →' T liste → unité Applique la fonction donnée à chaque élément de la collection.
iter2: ('T1 →' T2 → unité) → 'Liste T1 →' Liste T2 → unité Applique la fonction donnée à deux collections simultanément. Les collections doivent avoir une taille identique.
iteri: (int → 'T → unité) →' T liste → unité Applique la fonction donnée à chaque élément de la collection. L'entier passé à la fonction indique l'index de l'élément.
iteri2: (int → 'T1 →' T2 → unité) → 'Liste T1 →' Liste T2 → unité Applique la fonction donnée à deux collections simultanément. Les collections doivent avoir une taille identique. L'entier passé à la fonction indique l'index de l'élément.
longueur: 'T liste → int Renvoie la longueur de la liste.
carte: ('T →' U) → 'T liste →' U liste Crée une nouvelle collection dont les éléments sont les résultats de l'application de la fonction donnée à chacun des éléments de la collection.
map2: ('T1 →' T2 → 'U) →' Liste T1 → 'Liste T2 →' Liste U Crée une nouvelle collection dont les éléments sont les résultats de l'application de la fonction donnée aux éléments correspondants des deux collections par paires.
map3: ('T1 →' T2 → 'T3 →' U) → 'Liste T1 →' Liste T2 → 'Liste T3 →' Liste U Crée une nouvelle collection dont les éléments sont les résultats de l'application simultanée de la fonction donnée aux éléments correspondants des trois collections.
mapi: (int → 'T →' U) → 'T liste →' U liste Crée une nouvelle collection dont les éléments sont les résultats de l'application de la fonction donnée à chacun des éléments de la collection. L'index entier passé à la fonction indique l'index (à partir de 0) de l'élément en cours de transformation.
mapi2: (int → 'T1 →' T2 → 'U) →' Liste T1 → 'Liste T2 →' Liste U Comme List.mapi, mais en mappant les éléments correspondants à partir de deux listes de longueur égale.
max: 'T liste →' T Renvoie le plus grand de tous les éléments de la liste, comparé à l'aide d'Operators.max.
maxBy: ('T →' U) → 'T liste →' T Renvoie le plus grand de tous les éléments de la liste, comparé à l'aide d'Operators.max sur le résultat de la fonction.
min: 'T liste →' T Renvoie le plus bas de tous les éléments de la liste, comparé à l'aide de Operators.min.
minBy: ('T →' U) → 'T liste →' T Renvoie le plus bas de tous les éléments de la liste, comparé à l'aide d'Operators.min sur le résultat de la fonction
nième: 'T liste → int →' T Indexe dans la liste. Le premier élément a l'index 0.
ofArray: 'T [] →' T liste Crée une liste à partir du tableau donné.
ofSeq: seq <'T> →' T liste Crée une nouvelle liste à partir de l'objet énumérable donné.
partition: ('T → booléen) →' T liste * 'T liste Divise la collection en deux collections, contenant les éléments pour lesquels le prédicat donné retourne true et false respectivement.
permute: (int → int) → 'T liste →' T liste Renvoie une liste avec tous les éléments permutés selon la permutation spécifiée.
choisir: ('T →' U option) → 'T liste →' U Applique la fonction donnée aux éléments successifs, retournant le premier résultat où la fonction retourne Some pour une certaine valeur.
réduire: ('T →' T → 'T) →' T liste → 'T Applique une fonction à chaque élément de la collection, en enfilant un argument d'accumulateur dans le calcul. Cette fonction applique la fonction spécifiée aux deux premiers éléments de la liste. Il transmet ensuite ce résultat dans la fonction avec le troisième élément, et ainsi de suite. Enfin, il renvoie le résultat final. Si la fonction d'entrée est f et les éléments sont i0 ... iN, alors cette fonction calcule f (... (f i0 i1) i2 ...) iN.
reductionBack: ('T →' T → 'T) →' T liste → 'T Applique une fonction à chaque élément de la collection, en enfilant un argument d'accumulateur dans le calcul. Si la fonction d'entrée estf et les éléments sont i0 ... iN, alors cette fonction calcule f i0 (... (f iN-1 iN)).
répliquer: (int → 'T →' T liste) Crée une liste en appelant le générateur donné sur chaque index.
rev: 'T liste →' T liste Renvoie une nouvelle liste avec les éléments dans l'ordre inverse.
scan: ('State →' T → 'State) →' State → 'T list →' State list Applique une fonction à chaque élément de la collection, en enfilant un argument d'accumulateur dans le calcul. Cette fonction prend le deuxième argument et lui applique la fonction spécifiée ainsi que le premier élément de la liste. Ensuite, il passe ce résultat dans la fonction avec le deuxième élément et ainsi de suite. Enfin, il renvoie la liste des résultats intermédiaires et le résultat final.
scanBack: ('T →' State → 'State) →' T list → 'State →' State list Comme foldBack, mais renvoie les résultats intermédiaires et finaux
trier: 'T liste →' T liste Trie la liste donnée en utilisant Operators.compare.
sortBy: ('T →' Clé) → 'T liste →' T liste Trie la liste donnée en utilisant les clés données par la projection donnée. Les clés sont comparées à l'aide d'Operators.compare.
sortWith: ('T →' T → int) → 'T liste →' T liste Trie la liste donnée à l'aide de la fonction de comparaison donnée.
somme: ^ T liste → ^ T Renvoie la somme des éléments de la liste.
sumBy: ('T → ^ U) →' T liste → ^ U Renvoie la somme des résultats générés en appliquant la fonction à chaque élément de la liste.
queue: 'T liste →' T liste Renvoie la liste d'entrée sans le premier élément.
toArray: 'T liste →' T [] Crée un tableau à partir de la liste donnée.
toSeq: 'T liste → seq <' T> Affiche la liste donnée sous forme de séquence.
tryFind: ('T → bool) →' T liste → 'T option Renvoie le premier élément pour lequel la fonction donnée renvoie true. RevenirNone si aucun élément de ce type n'existe.
tryFindIndex: ('T → booléen) →' T liste → option int Renvoie l'index du premier élément de la liste qui satisfait le prédicat donné. RevenirNone si aucun élément de ce type n'existe.
tryPick: (option 'T →' U) → 'Liste T →' option U Applique la fonction donnée aux éléments successifs, retournant le premier résultat où la fonction retourne Somepour une certaine valeur. Si aucun élément de ce type n'existe, retournezNone.
décompressez: ('T1 *' T2) liste → 'T1 liste *' T2 liste Divise une liste de paires en deux listes.
décompressez3: ('T1 *' T2 * 'T3) liste →' T1 liste * 'T2 liste *' T3 liste Divise une liste de triplets en trois listes.
zip: 'Liste T1 →' Liste T2 → ('T1 *' T2) liste Combine les deux listes en une liste de paires. Les deux listes doivent avoir des longueurs égales.
zip3: 'Liste T1 →' Liste T2 → 'Liste T3 → (' T1 * 'T2 *' T3) liste Combine les trois listes en une liste de triplets. Les listes doivent avoir des longueurs égales.

Les exemples suivants illustrent les utilisations des fonctionnalités ci-dessus -

Exemple 1

Ce programme montre l'inversion d'une liste récursivement -

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)

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

Cependant, vous pouvez utiliser le rev fonction du module dans le même but -

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

Exemple 2

Ce programme montre le filtrage d'une liste à l'aide du List.filter méthode -

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

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]

Exemple 3

le List.map méthode mappe une liste d'un type à un autre -

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

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

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"]

Exemple 4

le List.append méthode et l'opérateur @ ajoute une liste à une autre -

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

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

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']

Exemple 5

le List.sortméthode trie une liste. leList.sum méthode donne la somme des éléments de la liste et la List.average méthode donne la moyenne des éléments de la liste -

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

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

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

Une opération de «repli» applique une fonction à chaque élément d'une liste, agrège le résultat de la fonction dans une variable d'accumulateur et renvoie l'accumulateur comme résultat de l'opération de repli.

Exemple 6

le List.fold applique une fonction à chaque élément de gauche à droite, tandis que List.foldBack applique une fonction à chaque élément de droite à gauche.

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 ])

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.