Разделение списка на список - PullRequest
0 голосов
/ 28 июня 2018

Как я могу конвертировать:

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

в

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

Подумал, что это будет самый простой способ показать, что я ищу. Я с трудом пытаюсь найти наиболее функциональный способ сделать это с большим списком, который должен быть разделен на определенный элемент. Этот элемент не отображается в новом списке списков. Любая помощь будет оценена!

Ответы [ 5 ]

0 голосов
/ 12 сентября 2018
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)
}
0 голосов
/ 29 июня 2018

Это самый чистый способ сделать это

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

Функция span разбивает список по первому значению, не соответствующему условию, а деструктуризация с левой стороны удаляет совпадающее значение из второго списка.

Это не удастся, если нет соответствующего значения.

0 голосов
/ 29 июня 2018

Если вы хотите поддерживать несколько экземпляров этого разделителя, вы можете использовать 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))
0 голосов
/ 29 июня 2018
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))
0 голосов
/ 28 июня 2018

Имеется список и разделитель, чтобы разделить список на 2:

val list = List(1, 1, 1, 1, 4, 2, 2, 2, 2)
val delimiter = 4
  • Вы можете использовать комбинацию List.indexOf, List.take и List.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))
...