如何将List拆分为元组?

时间:2013-01-28 21:47:07

标签: list scala

我正在尝试定义一个函数,该函数会使用列表并将其拆分n而不使用takedropgrouped

  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))

2 个答案:

答案 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)
}