// BLOG

Elm #6 - Collections

Elm propose différentes structures de données pour stocker un ensemble de données, on les appelle les "Coillections". Dans cette partie 6 nous allons voir plusieurs types de collections.

Rédigé le 13.10.2018
Par Gilles Vauvarin

Elm Programmation fonctionnelle

Les collections

Elm propose différentes structures de données pour stocker un ensemble de données :

Lists []

-- Liste de String
["Bob", "Nikki", "Angela"]

-- Liste de Int
[1, 2, 3]

Une liste contient uniquement des valeurs de même type et peut être manipulé en utilisant les fonctions du package List. https://package.elm-lang.org/packages/elm-lang/core/latest/List

Les éléments d’une liste peuvent être modifiés à l’aide de la méthode map. Le résultat sera une nouvelle liste.

-- list
numbers = [ 2, 4, 6 ]

-- fonction
double n = n * 2

-- mofification des éléments de la liste
List.map double numbers

> [4, 8, 12]

Tuples ()

-- Tuple contenant des valeurs de différents types
(True, "Hello world")

Les tuples contiennent un nombre limité de valeurs (2 min - 9 max) qui peuvent être de n’importe quels types.

Les tuples sont souvent utilisés par des fonctions pour retouner de multiples valeurs, c’est le cas par exemple de la fonction update que l’on retrouve dans tous les programmes Elm.

Records {}

Les records sont équivalents aux objets en JavaScript. Ils contiennent des éléments sous la forme “clé/valeur”.

Le pipe “|” permet de créer un nouveau record en mettant à jour certains champs d’un autre record.

-- Création d'un records "animal"
animal = { name = "Puppy", age = 2 }

-- Une mise à jour du record nécessite la création d'un nouveau record
newAnimal = { animal | age = 3 }

Pour accéder à la valeur d’un élément, il suffit de faire précéder le nom de la clé d’un élément par un point “.”

.name animal
> Puppy : String

-- On peut aussi écrire
animal.name
> Puppy : String

.age animal
> 2 : Number

Sets

Sets permet d’obtenir des collections de valeurs uniques. Cela signifie qu’un set ne contient jamais plusieurs éléments ayant la même valeur - il n’est donc pas nécessaire de filtrer les doublons d’un set.

Il est nécessaire d’importer le module Set pour pouvoir l’utilisae dans nos programmes.

On peut instancier une variable sets vide :

set = Set.empty

… ou utiliser la fonction fromList :

import HTML exposing (HTML, text)
import Set

set = Set.fromList [1,1,1,2]

main : HTML msg
main =
 text (String.fromSet set)

Après compilation, Elm renvoie le résultat suivant :

Set.fromList [1,2]

Sets peut être utile pour par exemple :

1- obtenir les éléments en communs entre deux collections.

2- unir deux collections en retirant les doublons,

3- trouver les différences entre deux collections

import Set

set1 = Set.fromList [1,2,3,4,3,2,1]
-- Set.fromList [1,2,3,4] : Set.Set number

set2 = Set.fromList [3,4,5,6]
-- Set.fromList [3,4,5,6] : Set.Set number

-- 1
intersection = Set.intersect set1 set2
-- Set.fromList [3,4] : Set.Set number

-- 2
union = Set.union set1 set2
-- Set.fromList [1,2,3,4,5,6] : Set.Set number

-- 3
differences = Set.diff set1 set2
-- Set.fromList [1,2] : Set.Set number

Arrays

Les tableaux sont très similaires aux listes en termes de comportement. Presque toutes les opérations qui peuvent être effectuées sur une liste peuvent l’être aussi sur un tableau.

Le langage Elm ne permet pas de créer de façon littéral un Array, nous devons créer d’abord une liste et de la transformer en tableau à l’aide de la fonction Array.fromList et cela nécessite l’import du module Array.

Création d’un Array :

import Array

-- Création d'un array à partir d'une liste et de la fonction "Array.fromList"
myArray = Array.fromList [ 1, 2, 3, 4 ]

Il est utile de créer un Array si l’on souhaite accéder à une donnée d’une liste via son index (ce qui n’est pas possible via une liste).

Pour retransformer un Array en List, on utilise la fonction Array.toList

Array.ToList myArray
[ 1, 2, 3, 4 ] : List number

Pour inclure un index pour chaque élément, on utilise la fonction toIndexedList

myAnimals = Array.fromList [ "Cat", "Dog", "Bird", "Horse" ]

Array.toIndexedList myAnimals

[(0,"Cat"),(1,"Dog"),(2,"Bird"),(3,"Horse")]
 : List ( Int, String )

Il y a d’autres manipulation possibles sur les “Array”. Consultez la documentation.

Dictionaries

La structure de données Dict enregistre des pairs de clé/valeur. Les clés doivent être uniques mais peuvent être de n’importe qul type. Ceci inclut Int, Float, Time, Char, String, et des tuples ou des listes de type comparable.

Les dictionnaries sont également créée en utilisant la fonction form.List et il est nécessaire d’importer le module Dict

module Main exposing (main)

import HTML exposing (HTML, text)
import Dict

dict =
 Dict.fromList
 [ ("keyOne", "valueOne")
 , ("keyTwo", "valueTwo")
 ]

main : HTML msg
main =
 text (String.fromDict dict)

Après complilation, Elm renverra la valeur :

Dict.fromList [("keyOne","valueOne"),("keyTwo","valueTwo")]

Autre exemple:

import Dict

users = Dict.fromList \
 [ ("Bob", { email = "mail@bob.com"}) \
 , ("Elena", { email = "mail@elena.org"}) \
 ]

usernames = Dict.keys users
-- ["Bob","Elena"] : List String

userRecords = Dict.values users
-- [{ email = "mail@bob.com" },{ email = "mail@elena.org" }] : List { email : String }

Bob = Dict.get "Bob" users
-- Just { email = "mail@bob.com " } : Maybe.Maybe { email : String }

Sources:

https://azer.bike/journal/elm/https://guide.elm-lang.org

https://dennisreimann.de/articles/elm-data-structures-list-array-set-dict.html

Disclaimer:
Etant un total débutant dans le langage Elm et la programmation fonctionnel, il se peut que des incompréhensions ou des erreurs se soient glissées dans mes explications. Si vous en remarquez, merci de me les signaler pour que je puisse les corriger au plus vite.