How do you stop building an Option[Collection] upon reaching the first None?

前端 未结 5 1324
夕颜
夕颜 2020-12-18 03:52

When building up a collection inside an Option, each attempt to make the next member of the collection might fail, making the collection as a whole a failure, t

5条回答
  •  鱼传尺愫
    2020-12-18 04:47

    Combining the other answers, i.e., a mutable flag with the map and takeWhile we love.

    Given an infinite stream:

    scala> var count = 0
    count: Int = 0
    
    scala> val vs = Stream continually { println(s"Compute $count") ; count += 1 ; count }
    Compute 0
    vs: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    

    Take until a predicate fails:

    scala> var failed = false
    failed: Boolean = false
    
    scala> vs map { case x if x < 5 => println(s"Yup $x"); Some(x) case x => println(s"Nope $x"); failed = true; None } takeWhile (_.nonEmpty) map (_.get)
    Yup 1
    res0: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    
    scala> .toList
    Compute 1
    Yup 2
    Compute 2
    Yup 3
    Compute 3
    Yup 4
    Compute 4
    Nope 5
    res1: List[Int] = List(1, 2, 3, 4)
    

    or more simply:

    scala> var count = 0
    count: Int = 0
    
    scala> val vs = Stream continually { println(s"Compute $count") ; count += 1 ; count }
    Compute 0
    vs: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    
    scala> var failed = false
    failed: Boolean = false
    
    scala> vs map { case x if x < 5 => println(s"Yup $x"); x case x => println(s"Nope $x"); failed = true; -1 } takeWhile (_ => !failed)
    Yup 1
    res3: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    
    scala> .toList
    Compute 1
    Yup 2
    Compute 2
    Yup 3
    Compute 3
    Yup 4
    Compute 4
    Nope 5
    res4: List[Int] = List(1, 2, 3, 4)
    

提交回复
热议问题