[英]SCALA: Fold method with conditions
I am still learning the basics of Scala, therefore I am asking for your understanding.我仍在学习 Scala 的基础知识,因此我请求您的理解。 Is it any possible way to use fold method to print only names beginning with "A"
是否有任何可能的方法使用折叠方法仅打印以“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: ")(_+_));
}
}
}
Have a look at the signature of foldLeft
看一下
foldLeft
的签名
def foldLeft[B](z: B)(op: (B, A) => B): B
where在哪里
z
is the initial value z
是初始值op
is a function taking two arguments, namely accumulated result so far B
, and the next element to be processed A
op
是一个 function 取两个 arguments ,即到目前为止的累加结果B
,下一个要处理的元素A
B
B
Now consider this concrete implementation现在考虑这个具体的实现
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
}
here这里
z = List.empty[String]
op = (accumulated: List[String], next: String) => if (predicate(next)) accumulated.prepended(next) else accumulated
Usually we would write this inlined and rely on type inference so we do not have two write out full types all the time, so it becomes通常我们会写这个内联并依赖类型推断,所以我们不会一直有两个写出完整类型,所以它变成
names.foldLeft(List.empty[String]) { (acc, next) =>
if (next.startsWith("A")) next :: acc else acc
}
// val res1: List[String] = List(Ann, Adam)
On of the key ideas when working with List
is to always prepend an element instead of append使用
List
时的一个关键想法是始终预先添加一个元素而不是 append
names.foldLeft(List.empty[String]) { (accumulated: List[String], next: String) =>
if (predicate(next)) accumulated.appended(next) else accumulated
}
because prepending is much more efficient.因为前置效率更高。 However note how this makes the accumulated result in reverse order, so
但是请注意这如何使累积的结果以相反的顺序排列,所以
List(Ann, Adam)
instead of perhaps required而不是可能需要
List(Adam, Ann)
so often-times we perform one last traversal by calling reverse
like so所以很多时候我们通过调用
reverse
来执行最后一次遍历
names.foldLeft(List.empty[String]) { (acc, next) =>
if (next.startsWith("A")) next :: acc else acc
}.reverse
// val res1: List[String] = List(Adam, Ann)
The answer from @Mario Galic is a good one and should be accepted. @Mario Galic 的回答很好,应该被接受。 (It's the polite thing to do).
(这是礼貌的做法)。
Here's a slightly different way to filter for starts-with-A strings.这是过滤以A 开头的字符串的一种稍微不同的方法。
val names: List[String] = List("Adam", "Mick", "Ann")
println(names.foldLeft("my list of items starting with A: "){
case (acc, s"A$nme") => acc + s"A$nme "
case (acc, _ ) => acc
})
//output: "my list of items starting with A: Adam Ann"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.