Fonctions génériques
Dernière mise à jour
Cet article vous a-t-il été utile ?
Dernière mise à jour
Cet article vous a-t-il été utile ?
↓ Accès \ Renvoie →
'T
ou 💥
'T option
Par index
list.[index]
item index
tryItem index
Premier élément
head
tryHead
Dernier élément
last
tryLast
→ Fonctions à préfixer par le module associé : Array
, List
ou Seq
→ Dernier paramètre, la "collection", omis par concision
→ 💥 : ArgumentException
ou IndexOutOfRangeException
Fonction \ Module
Array
List
Seq
head
O(1)
O(1)
O(1)
item
O(1)
O(n) ❗
O(n) ❗
last
O(1)
O(n) ❗
O(n) ❗
length
O(1)
O(n) ❗
O(n) ❗
append
/ @
2 collections de tailles N1 et N2
N1 + N2
concat
P collections de tailles N1..Np
N1 + N2 + ... + Np
zip
2 collections de même taille N ❗
N tuples
allPairs
2 collections de taille N1 et N2
N1 * N2 tuples
💡 @
= opérateur infixe alias de List.append
uniquement (Array, Seq)
::
vs Append @
Cons 1 :: [2; 3]
Élément ajouté en tête de liste
Liste paraît en ordre inverse 😕
Mais opération en O(1) 👍 -- (Tail
conservée)
Append [1] @ [2; 3]
Liste en ordre normal
Mais opération en O(n) ❗ -- (Nouvelle Tail
à chaque niveau)
Via un prédicat f : 'T -> bool
:
Quel élément \ Renvoie
'T
ou 💥
'T option
Premier trouvé
find
tryFind
Dernier trouvé
findBack
tryFindBack
Index du 1er trouvé
findIndex
tryFindIndex
Index du der trouvé
findIndexBack
tryFindIndexBack
Par valeur
Au moins un
contains value
Par prédicat f
Au moins un
exists f
"
Tous
forall f
Quels éléments
Par nombre
Par prédicat f
Tous ceux trouvés
filter f
Premiers ignorés
skip n
skipWhile f
Premiers trouvés
take n
takeWhile f
truncate n
☝ Notes :
Avec skip
et take
, 💥 exception si n > list.Length
; pas avec truncate
Alternative pour Array
: sélection par Range arr.[2..5]
Fonction prenant en entrée :
Une fonction de mapping f
Une collection d'éléments de type 'T
Fonction
Mapping f
Retour
Quel(s) élément(s)
map
'T -> 'U
'U list
Autant d'éléments
mapi
int -> 'T -> 'U
'U list
idem
collect
'T -> 'U list
'U list
flatMap
choose
'T -> 'U option
'U list
Moins d'éléments
pick
'T -> 'U option
'U
1er élément ou 💥
tryPick
'T -> 'U option
'U option
1er élément
map
vs mapi
mapi
≡ map
with index
map
: mapping 'T -> 'U
→ Opère sur valeur de chaque élément
mapi
: mapping int -> 'T -> 'U
→ Opère sur index et valeur de chaque élément
mapi
Hormis map
et iter
, aucune fonction xxx
n'a de variante en xxxi
.
💡 Utiliser indexed
pour obtenir les éléments avec leur index
map
vs iter
map
'T -> 'U
'U list
iter
'T -> unit
(= Action
en C#)
unit list
unit
On pourrait considérer iter
comme inutile, map
pouvant prendre une lambda 'T -> unit
en paramètre, mais c'est se tromper.
Avec une Seq
, map
ne consomme pas la séquence et donc ne déclenche pas immédiatement les actions pour chaque élément de la séquence !
👉 Conclusion : iter
correspond à un cas d'utilisation différent de map
.
(Idem respectivement pour iteri
et mapi
)
choose
, pick
, tryPick
Mapping f: 'T -> 'U option
→ Opération partielle : peut échouer à produire une valeur
→ D'où le type Option
en sortie
→ Exemple : tryParseInt: string -> int option
(cf. exemple ci-dessous)
Les fonctions choose
, pick
, tryPick
gèrent les Option
s produites par le mapping des éléments de la collection, de manière à obtenir en sortie :
choose : 'U collection
→ toutes les valeurs que le mapping a réussi à produire
pick : 'U
→ la 1ère valeur que le mapping a réussi à produire
→ ou 💥 si aucune valeur n'a été produite
tryPick : 'U option
→ la même 1ère valeur wrappée dans Some
→ ou None
si aucune valeur n'a été produite
Exemples :
choose
est équivalente conceptuellement à 3 opérations en 1 :
1. map f
qui renvoie une collection de 'U option
2. filter (Option.isSome)
pour ne garder que les options contenant une valeur
3. map (Option.get)
pour extraire ces valeurs
De même, pick
et tryPick
sont conceptuellement équivalentes à :
→ pick
≅ choose f >> head
→ tryPick
≅ choose f >> tryHead
filter
ou choose
?
find
/tryFind
ou pick
/tryPick
?
filter
, find
/tryFind
opèrent avec un prédicat 'T -> bool
, sans mapping
choose
, pick
/tryPick
opèrent avec un mapping 'T -> 'U option
filter
ou find
/tryFind
?
choose
ou pick
/tryPick
?
filter
, choose
renvoient tous les éléments trouvés/mappés
find
, pick
ne renvoient que le 1er élément trouvé/mappé
Maximum
max
maxBy projection
Minimum
min
minBy projection
Somme
sum
sumBy projection
Moyenne
average
averageBy projection
Décompte
length
countBy projection
Zero
Les fonctions sum
ne marchent que si le type des éléments dans la collection comporte un membre statique Zero
et une surcharge de l'opérateur +
:
💡 On peut utiliser LanguagePrimitives.GenericZero
pour récupérer le Zero
d'un type :
fold (f: 'U -> 'T -> 'U) (seed: 'U) list
foldBack (f: 'T -> 'U -> 'U) list (seed: 'U)
reduce (f: 'T -> 'T -> 'T) list
reduceBack (f: 'T -> 'T -> 'T) list
☝ f
prend 2 paramètres : un "accumulateur" acc
et l'élément courant x
💥 reduceXxx
plante si liste vide car 1er élément utilisé en tant que seed
Exemples :
Inversion
rev list
Tri ascendant
sort list
sortBy f list
Tri descendant
sortDescending list
sortDescendingBy f list
Tri personnalisé
sortWith comparer list
💡 Les éléments sont répartis en groupes.
Exemples en partant de [1..10]
Valeur initiale
[ 1 2 3 4 5 6 7 8 9 10 ]
chunkBySize 3
[[1 2 3] [4 5 6] [7 8 9] [10]]
splitInto 3
[[1 2 3 4] [5 6 7] [8 9 10]]
splitAt 3
([1 2 3],[4 5 6 7 8 9 10])
Tuple ❗
💡 Les éléments peuvent être dupliqués dans différents groupes.
Valeur initiale
[ 1 2 3 4 5 ]
pairwise
[(1,2) (2,3) (3,4) (4,5) ]
Tuples ❗
windowed 2
[[1 2] [2 3] [3 4] [4 5] ]
Listes de 2
windowed 3
[[1 2 3] [2 3 4] [3 4 5] ]
Listes de 3
partition
predicate: 'T -> bool
('T list * 'T list)
→ 1 tuple ([OKs], [KOs])
groupBy
projection: 'T -> 'K
('K * 'T list) list
→ N tuples [(clé, [éléments associés])]
Au choix : Dest.ofSource
ou Source.toDest
De / vers
Array
List
Seq
Array
×
List.ofArray
Seq.ofArray
×
Array.toList
Array.toSeq
List
Array.ofList
×
Seq.ofList
List.toArray
×
List.toSeq
Seq
Array.ofSeq
List.ofSeq
×
Seq.toArray
Seq.toList
×
Les fonctions de List
/Array
/Seq
peuvent souvent être remplacées par une compréhension c'est-à-dire une expression de construction d'une liste [...]
, d'un tableau [|...|]
ou d'une séquence seq {...}
respectivement. C'est une option à envisager pour améliorer la lisibilité.
Exemples pour les listes :
Le type de retour n'est pas le même : iter
renvoie unit
, alors que map
renverrait alors unit list
. Par contre, le compilateur n'oblige pas à ignorer cette valeur (cf. ), ce qui aiderait à détecter l'usage erroné de map
au lieu de iter
!?
Fonctions xxxBack
: tout est inversé / fonctions xxx
!
→ Parcours des éléments en sens inverse : dernier → 1er élément
→ Paramètres seed
et list
inversés (pour foldBack
vs fold
)
→ Paramètres acc
et x
de f
inversés