【问题标题】:Splitting a list of strings into several lists at every predicate scala在每个谓词 scala 处将字符串列表拆分为多个列表
【发布时间】:2022-01-10 14:18:06
【问题描述】:

有没有办法拆分字符串列表,如下所示:

List("lorem", "ipsum" ,"X", "sit", "amet", "consectetur")

在像x => x.equals("X") 这样的每个谓词中分成几个列表,结果将是:

List(List("lorem", "ipsum"), List("sit", "amet", "consectetur"))

这一切都以简单的功能方式实现?

【问题讨论】:

  • 你试过什么?这应该很容易使用尾递归,foldLeftList.unfold
  • 尝试了很多东西,比如 groupBy、map、partition.. foldLeft 更多地用于每个 x,y 元素之间的操作还是?

标签: scala functional-programming


【解决方案1】:

unfold() (Scala 2.13.x) 方式。

val lst =
  List("X","lorem","ipsum","X","sit","amet","X","consectetur","X")

List.unfold(lst){st =>
  Option.when(st.nonEmpty){
    val (nxt, rst) = st.span(_ != "X")
    (nxt, rst.drop(1))
  }
}
//res0: List[List[String]] = List(List()
//                              , List(lorem, ipsum)
//                              , List(sit, amet)
//                              , List(consectetur))

【讨论】:

    【解决方案2】:

    您可以使用尾递归函数轻松跟踪每个块,如下所示:

    def splitEvery[A](data: List[A])(p: A => Boolean): List[List[A]] = {
      @annotation.tailrec
      def loop(remaining: List[A], currentChunk: List[A], acc: List[List[A]]): List[List[A]] =
        remaining match {
          case a :: tail =>
            if (p(a))
              loop(
                remaining = tail,
                currentChunk = List.empty,
                currentChunk.reverse :: acc
              )
            else
              loop(
                remaining = tail,
                a :: currentChunk,
                acc
              )
          
          case Nil =>
            (currentChunk.reverse :: acc).reverse
        }
      
      loop(
        remaining = data,
        currentChunk = List.empty,
        acc = List.empty
      )
    }
    

    可以这样使用:

    val data = List("lorem", "ipsum" ,"X", "sit", "amet", "consectetur")
    val result = splitEvery(data)(_ == "X")
    // result: List[List[String]] = List(List(lorem, ipsum), List(sit, amet, consectetur)
    )
    

    可以看到运行here的代码

    【讨论】:

      猜你喜欢
      • 2011-11-09
      • 2010-10-09
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      相关资源
      最近更新 更多