J'essayais de résumer tous les éléments d'une liste, ils sont de type Option [Int], si l'un d'entre eux est Aucun, le résultat complet est Aucun, si tous sont Certains (valeur), je veux la somme de tous:

val ls = List(Some(2), Some(5), Some(4), Some(1))

ls.fold(None)((rs,x) => for(n <- x; m <- rs) yield {n+m})

Mais je reçois toujours Aucun, quoi qu'il arrive.

0
Damián Rafael Lattenero 16 nov. 2017 à 17:55

5 réponses

Meilleure réponse

Essayez aussi ceci:

val ls = List(Some(2), Some(5), Some(4), Some(1))
val sum = ls.foldLeft(Option(0))((so, io) => so.flatMap(s => io.map(s + _)))

Si une seule valeur de la liste est None, alors sum est signalé comme None; sinon - si toutes les valeurs sont définies - vous obtenez un Some contenant la somme des éléments. Si la liste est vide, vous obtiendrez Some(0) comme résultat.

4
FunctionalWannabe 16 nov. 2017 à 16:36

Juste:

ls.foldLeft (0) (_ + _.getOrElse (0))

Ou même

(0 /: ls) (_ + _.getOrElse (0))
0
user unknown 18 avril 2018 à 21:03

Vous pouvez le faire et renvoyer uniquement un Int. Cela évite également d'itérer plusieurs fois le List.

val foo = List(Some(1), Some(2), None, Some(3))

foo.foldLeft(0)((acc, optNum) => acc + optNum.getOrElse(0))
0
JPotts 18 avril 2018 à 20:57

Utilisez d'abord forall pour vérifier si toutes les valeurs sont définies ou non, puis appliquez fold pour obtenir la somme si elle est définie sinon None.

scala> val ls = List(Some(2), Some(5), Some(4), Some(1))
ls: List[Some[Int]] = List(Some(2), Some(5), Some(4), Some(1))

scala> if(ls.forall(_.isDefined)) Some(ls.flatten.foldLeft(0){_ + _ }) else None
res22: Option[Int] = Some(12)

scala> val ls = List(Some(2), None,Some(5), Some(4), Some(1),None)
ls: List[Option[Int]] = List(Some(2), None, Some(5), Some(4), Some(1), None)

scala> if(ls.forall(_.isDefined)) Some(ls.flatten.foldLeft(0){_ + _ }) else None
res23: Option[Int] = None

scala>
1
Mahesh Chand 16 nov. 2017 à 16:43

Je réalise quelle était mon erreur, c'était le cas de base en pli:

val ls = List(Some(2), Some(5), Some(4), Some(1))

ls.fold(Some(0))((rs,x) => for(n <- x; m <- rs) yield {n+m})

Au lieu de None comme case Base, je mets 0, mais avec le contexte d'Option.

1
Damián Rafael Lattenero 16 nov. 2017 à 14:58
47332770