scala - SCALA:带条件的折叠方法
问题描述
我仍在学习 Scala 的基础知识,因此我请求您的理解。是否有任何可能的方法使用折叠方法仅打印以“A”开头的名称
Object Scala {
val names: List[String] = List("Adam", "Mick", "Ann");
def main(args: Array[String]) {
println(names.foldLeft("my list of items starting with A: ")(_+_));
}
}
}
解决方案
看一下签名foldLeft
def foldLeft[B](z: B)(op: (B, A) => B): B
在哪里
z
是初始值op
是一个接受两个参数的函数,即到目前为止的累积结果B
和要处理的下一个元素A
- 返回累计结果
B
现在考虑这个具体的实现
val names: List[String] = List("Adam", "Mick", "Ann")
val predicate: String => Boolean = str => str.startsWith("A")
names.foldLeft(List.empty[String]) { (accumulated: List[String], next: String) =>
if (predicate(next)) accumulated.prepended(next) else accumulated
}
这里
z = List.empty[String]
op = (accumulated: List[String], next: String) => if (predicate(next)) accumulated.prepended(next) else accumulated
通常我们会写这个内联并依赖类型推断,所以我们不会一直有两个写出完整类型,所以它变成
names.foldLeft(List.empty[String]) { (acc, next) =>
if (next.startsWith("A")) next :: acc else acc
}
// val res1: List[String] = List(Ann, Adam)
使用时的关键思想List
是始终预先添加元素而不是附加
names.foldLeft(List.empty[String]) { (accumulated: List[String], next: String) =>
if (predicate(next)) accumulated.appended(next) else accumulated
}
因为前置效率更高。但是请注意这如何使累积的结果以相反的顺序排列,所以
List(Ann, Adam)
而不是可能需要
List(Adam, Ann)
很多时候我们通过reverse
这样调用来执行最后一次遍历
names.foldLeft(List.empty[String]) { (acc, next) =>
if (next.startsWith("A")) next :: acc else acc
}.reverse
// val res1: List[String] = List(Adam, Ann)
推荐阅读
- java - 我该如何改进这段代码?另外我想知道为什么每次我运行这段代码时文件中的内容总是被覆盖?
- python - 谁能详细解释 linalg.lstsq 的回归?
- r - 有效地在 r 中随机替换向量中的数字
- r - fct_unique 和 unique 有什么区别?
- makefile - Makefiles:如何正确使用 $wildcard 递归下降?
- r - 如何自动增加最大值和重要性栏之间的空间并在中间有重要性标签?
- linux - 如何将字符串附加到文本文件中
- python - 我已经从 pyqt 设计师设计了 ui 现在我想将该按钮和标签连接在一起
- android - 后退按钮总是触发前一个活动的 onCreate() 除非 launchMode 是 singleTop
- node.js - 将所有日志写入控制台或使用日志库附加程序?