【问题标题】:Looking for a nice way to split [duplicate]寻找一种分裂的好方法[重复]
【发布时间】:2021-02-19 07:42:26
【问题描述】:

我正在尝试在 Scala 中的拆分点拆分列表。

例如,拆分以下列表:

List(2,6,4,7,9,10),分裂点为 4

会导致:

result: List[List[Int]] = List(List(2, 6, 4, 7), List(9, 10))

【问题讨论】:

  • 不是不想用。我只是希望尽可能少地使用标准库
  • 因此,您实际上是在使用足够的 Scala 语法编写 C 代码以使其混乱。
  • @jwvh 公平地说,splitAt 的实际实现看起来非常像 C 代码!
  • 如果这是学习递归的某种分配,我可能会理解不使用内置函数。否则我真的不明白不使用stdlib有什么意义?
  • @Tim 我的观点完全正确!

标签: split


【解决方案1】:

这是您的split 函数的功能版本:

def split[A](ls: List[A], n: Int): List[List[A]] = {
  @annotation.tailrec
  def loop(rem: List[A], take: Int, taken: List[A]): List[List[A]] =
    rem match {
      case hd :: tail if take > 0 =>
        loop(tail, take - 1, hd +: taken)
      case _ =>
        List(taken.reverse, rem)
    }

  loop(ls, n, Nil)
}

splitAt 的实际实现使用非函数技术,例如可变值和 while 循环。

请注意,还有很多库代码,因为List 是一个库类。

【讨论】:

    【解决方案2】:

    如果你不想使用任何内置函数,你至少可以看看源代码。在您的情况下,您应该检查.splitAt(...) 功能并稍微调整它

    def split(l: List[Int], n: Int) = {
      val b = new ListBuffer[Int]
      var i = 0
      var these = l
      while (!these.isEmpty && i < n) {
        i += 1
        b += these.head
        these = these.tail
      }
      (b.toList, these)
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用splitAt,根据docs

      将此集合拆分为给定位置的前缀/后缀对。

      注意:c splitAt n 等价于(但可能更有效)(c take n, c drop n)。

      注意:可能会针对不同的运行返回不同的结果,除非对底层集合类型进行了排序。

      因此你可以这样做:

      List(2,6,4,7,9,10).splitAt(4)
      

      请注意,这会返回一个元组。如果你想将其转换为列表,可以阅读enter link description here

      代码在Scastie运行

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-25
        • 2019-07-04
        • 1970-01-01
        相关资源
        最近更新 更多