【问题标题】:Scala takeWhile Method with foldLeft and foldRight带有 foldLeft 和 foldRight 的 Scala takeWhile 方法
【发布时间】:2017-11-04 00:08:24
【问题描述】:

我需要使用 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)

当条件不满足时如何让它停止?

【问题讨论】:

  • 毫无疑问,您有理由重新发明 takeWhile。我认为您需要做的是使您的累加器成为 List[Int] 和 Boolean 的元组。只要后者是真的,你就会继续。最后,当然你会想要为你的结果只提取 List[Int] 。当然,您的运算符现在会稍微复杂一些。此外,您可能想尝试反转 z :: a 和 a :: z。
  • 你必须使用 fold* 方法吗?它们不是为此而设计的,它们循环整个集合。如果您设置使用折叠,您可以执行诸如调用返回之类的操作,或者可能抛出异常以提前退出。见stackoverflow.com/questions/12892701/abort-early-in-a-fold

标签: scala


【解决方案1】:

一种方法如下(与您所做的几乎相同):

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 操作。

对不起,我修改了您的代码(其他括号等),但复制时没有编译。

【讨论】:

    【解决方案2】:

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

    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
    }
    

    【讨论】:

      【解决方案3】:

      这是使用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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 2011-09-09
        • 1970-01-01
        • 2012-03-25
        相关资源
        最近更新 更多