DennisVDB - 1 year ago 131
Scala Question

# Sum a list of options in Scala

How can I sum a list of options (

`List[Option[Double]]`
) with the following rules?

• `List(Some(1), ..., Some(n)) --> Some(1 + ... + n)`

• `List(Some(1), ..., Some(n), None) --> None`

• `List(None, ..., None) --> None`

To avoid the traversal of the entire list with a `forall` to check if the entire set of options is defined, you could use a `foldLeft`, and use the fact that you can yield a `None` the first time you find an empty element in the chain.

``````def sumList[T : Numeric](list: List[Option[T]]): Option[T] = {
val numeric = implicitly[Numeric[T]]
list.foldLeft(Option(numeric.zero)) { case (acc, el) =>
el.flatMap(value => acc.map(ac => numeric.plus(ac, value)))
}
}

sumList(List(None, None, Some(5)))
res10: Option[Int] = None

scala> sumList(List(None, None, Some(5F)))
res11: Option[Float] = None

scala> sumList[Double](List(None, None, None))
res13: Option[Double] = None

scala> sumList(List(Some(5), Some(15)))
res14: Option[Int] = Some(20)
``````

And to avoid `return` you could simply use recursion(update, return is not needed above, but maybe this is easier to follow):

``````def sumListRec[T : Numeric](list: List[Option[T]], acc: T): Option[T] = {
val numeric = implicitly[Numeric[T]]

list match {
// if the list still has elements
// add the value to the accumulator and keep going
case Some(value) => sumListRec(tail, numeric.plus(acc, value))
// if you found a None, disregard whatever sum we built so far
// and just return None
case None => None
}
// If the list is empty, it means we've successfully reached
// the end of the list, so we just return the sum we built.
case Nil => Some(acc)
}
}
``````

Watch it in action:

``````scala> sumListRec(List(Some(5D), Some(5D)), 0D)
res5: Option[Double] = Some(10.0)

sumListRec(List(None, None, Some(5D)), 0D)
res2: Option[Double] = None

scala> sumListRec(List(None, None), 0D)
res6: Option[Double] = None
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download