简体   繁体   English

使用列表作为累加器的折叠方法

[英]Fold method using List as accumulator

To find prime factors of a number I was using this piece of code : 为了找到一个数字的主要因子,我正在使用这段代码:

 def primeFactors(num: Long): List[Long] = {
   val exists = (2L to math.sqrt(num).toLong).find(num % _ == 0)
    exists match {
     case Some(d) => d :: primeFactors(num/d)
     case None => List(num)
  }
}

but this I found a cool and more functional approach to solve this using this code: 但是我发现使用此代码可以解决此问题的一种更酷,更实用的方法:

def factors(n: Long): List[Long] = (2 to math.sqrt(n).toInt)
.find(n % _ == 0).fold(List(n)) ( i => i.toLong :: factors(n / i)) 

Earlier I was using foldLeft or fold simply to get sum of a list or other simple calculations, but here I can't seem to understand how fold is working and how this is breaking out of the recursive function.Can somebody plz explain how fold functionality is working here. 之前我只是使用foldLeftfold来获取列表的总和或其他简单的计算,但是在这里我似乎无法理解fold的工作方式以及它如何脱离递归函数。有人可以解释一下fold功能在这里工作。

Option's fold 期权的fold

If you look at the signature of Option 's fold function, it takes two parameters: 如果查看Optionfold函数的签名,则它带有两个参数:

def fold[B](ifEmpty: => B)(f: A => B): B

What it does is, it applies f on the value of Option if it is not empty. 它的作用是,如果不为空,它将对Option的值应用f If Option is empty, it simply returns output of ifEmpty (this is termination condition for recursion). 如果Option为空,则仅返回ifEmpty输出(这是递归的终止条件)。

So in your case, i => i.toLong :: factors(n / i) represents f which will be evaluated if Option is not empty. 因此,在您的情况下, i => i.toLong :: factors(n / i)表示f ,如果Option不为空,则将对其进行评估。 While List(n) is termination condition. List(n)是终止条件。

fold used for collection / iterators fold用于收集/迭代器

The other fold that you are taking about for getting sum of collection, comes from TraversableOnce and it has signature like: 您要获取总和的另一fold来自TraversableOnce ,它的签名如下:

def foldLeft[B](z: B)(op: (B, A) => B): B

Here, z is starting value (suppose incase of sum it's 0 ) and op is associative binary operator which is applied on z and each value of collection from left to right. 在这里, z是起始值(假设总和为0 ), op是关联二进制运算符,该op符应用于z并且collection的每个值从左到右。

So both fold s differ in their implementation. 因此,两个fold的实现方式都不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM