使用foldLeft和foldRight的Scala takeWhile方法

时间:2017-06-02 14:26:13

标签: scala

我需要使用foldLeft()和foldRight()来创建takeWhile()。 我想出了这个:

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
    ls.foldLeft(List[Int]())(a,z) =>
    if (p(z)) z :: a
    else a)
}

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
    ls.foldRight(List[Int]())(a,z) =>
    if (p(a)) a :: z
    else z)
}

但是当我打电话的时候用foldLeft

takeWhile(List(1,2,3,4,5), _< 3)
takeWhile(List(1,2,3,4,5), _> 4)
takeWhile(List(5,6,7,1,2,5), _> 4)

返回

List(2,1)
List(5)
List(5,7,6,5)

使用foldRight,我得到了

List(5)
List(5,6,7,5)

但它应该是

List(1,2)
List()
List(5,6,7)

如果不满足条件,我该如何停止?

3 个答案:

答案 0 :(得分:2)

一种方法是做以下事情(与你做的几乎一样):

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
    ls.foldLeft(List[Int]()){
      case (a,z) =>
      if (p(z)) z :: a
      else return a.reverse
    }
}

它打印以下内容:

List(1, 2)
List()
List(5, 6, 7)

return从takeWhile方法返回,因此它可以执行您想要的操作,因为它会停止foldLeft - 操作。

抱歉,我修改了你的代码(其他括号等),但是在复制时没有编译。

答案 1 :(得分:1)

这是让foldLeft()工作的一种方法。这很糟糕,但它完成了工作并且它是一个起点:

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
  ls.foldLeft((List[Int](), true)) {
    (a, z) =>
      if (a._2 && p(z)) (z :: a._1, a._2)
      else (a._1, false)
  }._1.reverse
}

答案 2 :(得分:0)

在这里使用foldRight(因为您要求两者):

def takeWhile[T](list: List[T], p: T => Boolean) =
  list.foldRight(List.empty[T]){
    case (t, l) if p(t) => t :: l
    case (t, l) => Nil
  }

只要找到不应该使用的值,它就会将状态重新初始化为Nil