Scala:使用谓词为子列表拆分列表

Ger*_*mán 2 functional-programming scala

我只是有一个用例,我需要将列表拆分为n个子列表,以便从原始列表中按顺序获取元素并对子列表的谓词为true进行分组(当它为false时,启动新的子列表) .我没有在标准库中找到这个功能,我认为尝试以功能方式解决它是一个很好的练习(因为我远非功能大师).

以下是我提出的代码.但我怀疑它可以改进很多.你能帮我找一个更好的代码编码方法吗?

class ListWithSplitter[A](val theList:List[A])
{
  private def sublistWhile(list:List[A], pred:(List[A] => Boolean)):(List[A],List[A]) =
  {
    def combine(okList:List[A], remaining:List[A], pred:(List[A] => Boolean)):(List[A],List[A]) =
    {
      if(pred(okList ::: remaining.head :: Nil))
        combine(okList ::: remaining.head :: Nil, remaining.tail, pred)
      else
        (okList, remaining)
    }

    list match {
      case Nil => (Nil, Nil)
      case x :: Nil => (list, Nil)
      case x :: xs => combine(List(x), xs, pred)
    }
  }

  private def combinedSplit(list:List[A], pred:(List[A] => Boolean)):List[List[A]] =
  {
    val r = sublistWhile(list, pred)
    r match {
      case (Nil, Nil) => List(Nil)
      case (x, Nil) => List(x)
      case (x, y) => x :: combinedSplit(y, pred)
    }
  }

  def combinedSplit(pred:(List[A] => Boolean)):List[List[A]] =
  {
    combinedSplit(theList, pred)
  }
}

trait ListCombinedSplit
{
  implicit def list2combSplitter[A](x:List[A]) : ListWithSplitter[A] = new ListWithSplitter(x)
}

object ListSplitter extends ListCombinedSplit {

  def main(args:Array[String])
  {
    // sample usage: sum of each sublist is less than 100
    val a = List(4, 59, 10, 24, 42, 9, 2, 44, 44, 44, 44)
    val b = a combinedSplit { list:List[Int] => ((0 /: list)(_ + _)) < 100 }

    b foreach println
  }
}
Run Code Online (Sandbox Code Playgroud)

样本结果如下:

List(4, 59, 10, 24)
List(42, 9, 2, 44)
List(44, 44)
List(44)
Run Code Online (Sandbox Code Playgroud)

ron*_*ron 5

以下内容如何:

def toggledPartition[A](xs: List[A])(p: A => Boolean): List[List[A]] =
  if (xs.isEmpty) Nil
  else xs span p match { case (a,b) => a :: toggledPartition(b)(x => !p(x)) }
Run Code Online (Sandbox Code Playgroud)

可在http://ideone.com/HBrOv上运行的示例

顺便说一下,我觉得我在scalaz中看到了类似功能的东西,但是不记得在哪里.