我正在尝试定义一个函数,该函数会使用列表并将其拆分n
而不使用take
,drop
或grouped
def mySplit[X](n: Int, xs: List[X]): (List[X], List[X]) = {
if (n <= 0) (Nil, xs)
else
if (n >= xs.size) (xs, Nil)
else
if (n < xs.tail.size) (xs.head :: mySplit(n, xs.tail), Nil)
else (Nil, xs.head :: mySplit(n, xs.tail))
}
这就是我的想法。如果n < xs.tail.size
我们可以构建元组1(代表第1部分),否则我们可以处理元组2(列表的第二部分)。
以上不起作用。当我构建元组的一部分时,它似乎不喜欢::
。
我是以正确的方式接近这个吗?
示例:mySplit(3, (1 to 5).toList)
应返回(List(1,2,3), List(4,5))
答案 0 :(得分:3)
这是我的看法,从头开始重写:
def mySplit[X](n: Int, xs: List[X]): (List[X], List[X]) = {
xs match {
case Nil => (Nil, Nil)
case head :: tail =>
if(n == 0)
(Nil, xs)
else
mySplit(n - 1, tail) match {
case (before, after) =>
(head :: before, after)
}
}
}
或者更短和更短:
def mySplit[X](n: Int, xs: List[X]): (List[X], List[X]) = {
n match {
case 0 => (Nil, xs)
case s =>
mySplit(s - 1, xs.tail) match {
case (before, after) =>
(xs.head :: before, after)
}
}
}
答案 1 :(得分:1)
如果您仍想分割大型列表,这里是一个尾递归变量。它也更快:
import scala.annotation.tailrec
def mySplit[X](n: Int, xs: List[X]): (List[X], List[X]) = {
require(n >= 0)
if (n > 0) {
var result: (List[X], List[X]) = null
@tailrec
def mySplit0(n: Int, l: List[X], r: List[X]): Unit = r match {
case h :: t if (n > 0) => mySplit0(n - 1, h :: l, t)
case _ => result = (l.reverse, r)
}
mySplit0(n, Nil, xs)
result
} else (Nil, xs)
}