首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从列表中过滤项目并在Scala中计数的惯用方法是什么?

从列表中过滤项目并在Scala中计数的惯用方法是什么?
EN

Stack Overflow用户
提问于 2016-03-16 17:49:02
回答 3查看 127关注 0票数 1

我发现我经常会有一个选项列表(或者是八大选项或尝试列表),我想在整理列表之前,先数一下Nones的数量。有没有一种很好的惯用的方法可以不需要我多次处理列表呢?

就像这样,但更好:

代码语言:javascript
运行
复制
val sprockets: List[Option[Sprockets]] = getSprockets()
println("this many sprockets failed to be parsed" + sprockets.filter(_.isEmpty).count) 
println(sprockets.flatten)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-16 22:02:24

我会像戴尼斯所建议的那样使用折叠,例如:

代码语言:javascript
运行
复制
  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
票数 2
EN

Stack Overflow用户

发布于 2016-03-16 18:34:00

可能是递归?

代码语言:javascript
运行
复制
 @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) 
 }
票数 1
EN

Stack Overflow用户

发布于 2016-03-16 18:22:50

这就是你要找的吗?

代码语言:javascript
运行
复制
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)将抵消两次遍历情况下的额外循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36043226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档