Aujourd’hui nous vous proposons d’étudier un problème assez simple, qui peut arriver dans la vie de tous les jours d’un développeur.7
Disons que nous avons une liste de valeurs optionnelles. Nous voulons produire une seule valeur à partir de cette liste, si la liste est non vide. Le résultat produit sera donc lui aussi de type Option.
Enfin nous voulons séparer les valeurs (si il y en a au moins 2) avec un caractère de notre choix.
- Exemple 1 : Avoir List(Some("A"), None, Some("B")) en entrée devrait produire le résultat Some("A,B").
- Exemple 2 : Avoir List(None) en entrée devrait produire None.
En Scala
Nous pouvons utiliser la méthode flip de ZIO-prelude (ou la méthode sequence de Cats) pour transformer une List[Option[String]] en Option[List[String]] .
val list = List(Some("A"), None, Some("B"))
val flippedList = list.filter(_.isDefined).flip // <- Option(List(A,B))
flippedList.map(_.mkString(",")) // <- Some(A,B)
Note : si nous avions souhaité produire simplement une chaine (qui pourrait être vide), nous aurions pu supprimer le wrapper Option et toutes les valeurs non définies (None) de cette manière :
val flattenList = List(Some("A"), None, Some("B")).flatten // <- List(A, B)
flattenList.mkString(",")
En Kotlin
En Kotlin, nous utilisons en général les types nullables en remplacement des options :
val list = listOf("a", null, "b")
val result = list.filterNotNull().joinToString(separator=",").ifBlank { null }
En Java
En Java nous allons utiliser l’API Stream, le résultat est un peu plus verbeux, mais tout de même satisfaisant.
Stream::flatMap nous permet de supprimer tous les éléments non définis, et de retirer le wrapper Optional (comme flatten en Scala).
List<Optional<String>> list = List.of(Optional.of("A"), Optional.empty(), Optional.of("B"));
var result = Optional.of(
list.stream()
.flatMap(Optional::stream)
.collect(Collectors.joining( "," ))
).filter(Predicate.not(String::isEmpty));
Retour aux articles