我发现我经常会得到一个选项列表(或者Eithers或Trys),我想在列出列表之前计算Nones的数量。有没有一个很好的惯用方法来做这个并不需要我多次处理这个列表?
这样的东西,但更好:
val sprockets: List[Option[Sprockets]] = getSprockets()
println("this many sprockets failed to be parsed" + sprockets.filter(_.isEmpty).count)
println(sprockets.flatten)
答案 0 :(得分:2)
我会像Daenyth建议的那样使用折叠,比如这样的事情:
val list = List(Some(1),None,Some(0),Some(3),None)
val (flatList,count) = list.foldLeft((List[Int](),0)){
case ((data,count), Some(x)) => (data :+ x, count)
case ((data,count), None) => (data, count +1)
}
//output
//flatList: List[Int] = List(1, 0, 3)
//count: Int = 2
答案 1 :(得分:1)
可能是递归?
@tailrec
def flattenAndCountNones[A](in: Seq[Option[A]], out: Seq[A] = Queue.empty[A], n: Int = 0): (Seq[A], Int) = in match {
case Nil => (out, n)
case Some(x) :: tail => flattenAndCountNones(tail, out :+ x, n)
case None :: tail => flattenAndCountNones(tail, out, n + 1)
}
答案 2 :(得分:0)
这是你要找的吗?
val foo = List(Some(3), Some(4), None:Option[Int], Some(5), Some(6))
val (concatenatedList, emptyCount) =
foo.map(entry =>
(entry.toList, if (entry.isEmpty) 1 else 0)
).fold((List[Int](), 0))((a, b) =>
(a._1 ++ b._1, a._2 + b._2)
)
这是一次通过,但我不确定它是否真的比在两个方面做得更有效 - 在这种情况下,额外的对象创建(Tuple2s)将在两遍情况下抵消额外的循环