将列表拆分为列表

时间:2018-06-28 20:43:21

标签: scala list time split functional-programming

我如何转换:

List(1,1,1,1,4,2,2,2,2)

进入:

List(List(1,1,1,1), List(2,2,2,2))

这将是显示我正在寻找的最简单的方法。我很难找到一个最实用的方法来处理需要在特定元素上分开的大量列表。此元素不会显示在新的列表列表中。任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:3)

如果要支持该分隔符的多个实例,可以将foldRight与一些列表“体操”一起使用:

// more complex example: separator (4) appears multiple times
val l = List(1,1,1,1,4,2,2,2,2,4,5,6,4)

val separator = 4

val result = l.foldRight(List[List[Int]]()) {
  case (`separator`, res) => List(Nil) ++ res
  case (v, head :: tail) => List(v :: head) ++ tail
  case (v, Nil) => List(List(v))
}

// result: List(List(1, 1, 1, 1), List(2, 2, 2, 2), List(5, 6))

答案 1 :(得分:2)

给出一个列表和一个定界符,以便将列表拆分为2:

val list = List(1, 1, 1, 1, 4, 2, 2, 2, 2)
val delimiter = 4
  • 您可以结合使用List.indexOfList.takeList.drop

    val splitIdx = list.indexOf(delimiter)
    List(list.take(splitIdx), list.drop(splitIdx + 1))
    
  • 您可以使用List.span将给定谓词的列表分成一个元组:

    list.span(_ != delimiter) match { case (l1, l2) => List(l1, l2.tail) }
    

为了生产:

List(List(1, 1, 1, 1), List(2, 2, 2, 2))

答案 2 :(得分:2)

这是最干净的方法

val (l, _ :: r) = list.span( _ != 4)

span函数将列表拆分为与条件不匹配的第一个值,左侧的解构将匹配的值从第二个列表中移除。

如果没有匹配的值,它将失败。

答案 3 :(得分:1)

scala> val l = List(1,1,1,1,4,2,2,2,2)
l: List[Int] = List(1, 1, 1, 1, 4, 2, 2, 2, 2)

scala> l.splitAt(l.indexOf(4))
res0: (List[Int], List[Int]) = (List(1, 1, 1, 1),List(4, 2, 2, 2, 2))

答案 4 :(得分:0)

def convert(list: List[Int], separator: Int): List[List[Int]] = {
  @scala.annotation.tailrec
  def rec(acc: List[List[Int]], listTemp: List[Int]): List[List[Int]] = {
    if (listTemp.isEmpty) acc 
    else {
      val (l, _ :: r) = listTemp.span(_ != separator)
      rec(acc ++ List(l), r)
    }
  }

  rec(List(), list)
}