L oop над списком, каждый раз получая увеличивающееся количество элементов - PullRequest
3 голосов
/ 28 мая 2020

Допустим, у меня есть список, который выглядит как

{A, B, C, D, E}  

И я хочу l oop над этим списком, получая каждый раз увеличивающееся количество элементов, поэтому каждая итерация будет выглядеть так:

Iteration 1: {A}  
Iteration 2: {A, B}
Iteration 3: {A, B, C}  
Iteration 4: {A, B, C, D}
Iteration 5: {A, B, C, D, E}  

В настоящее время я достигаю этого с помощью:

(1 to list.size).foreach( n => {
  val elements = list.take(n)
  // Do something with elements
})

Но это кажется беспорядочным. Есть ли более «scala» способ добиться такого поведения?

Ответы [ 3 ]

2 голосов
/ 28 мая 2020

Вы можете использовать list.inits:

scala> List(1,2,3,4,5).inits.foreach(println)
List(1, 2, 3, 4, 5)
List(1, 2, 3, 4)
List(1, 2, 3)
List(1, 2)
List(1)
List()

Чтобы получить желаемый результат, вам нужно будет создать список из итератора, перевернуть его и взять хвост, чтобы пропустить пустой список:

scala> List(1,2,3,4,5).inits.toList.reverse.tail.foreach(println)
List(1)
List(1, 2)
List(1, 2, 3)
List(1, 2, 3, 4)
List(1, 2, 3, 4, 5)
0 голосов
/ 28 мая 2020

Вот рекурсивная версия. Сначала вам нужно будет перевернуть список.

@tailrec
def doIt(l: List[Int], acc: List[List[Int]] = Nil): List[List[Int]] = l match {
  case Nil => acc
  case h :: t => doIt(t, List(h) :: acc.map(l => h :: l))
}


doIt(List(1,2,3).reverse).foreach(println)

// output
List(1)
List(1, 2)
List(1, 2, 3)
0 голосов
/ 28 мая 2020

Вы можете использовать foldLeft со связанным списком для накопления элементов.

Однако это изменит порядок, поэтому вам нужно будет вызвать функцию .reverse, если вы действительно заботитесь о порядок, что неэффективно.

list.foldLeft(Nil : List[String]){(l, n) => {
  val elements = n :: l
  println(elements)
  elements
}}

Вывод:

List(A)
List(B, A)
List(C, B, A)
List(D, C, B, A)
List(E, D, C, B, A)

Вот версия, которая сохраняет порядок, но использует ListBuffer, что не очень хорошо

val elems = ListBuffer[String]()
list.foreach{ s => 
  elems += s
  println(elems)
}

То же, но со складкой

list.foldLeft(ListBuffer[String]()){(elems, s) => 
  elems += s
  println(elems)
  elems
}

Вывод:

ListBuffer(A)
ListBuffer(A, B)
ListBuffer(A, B, C)
ListBuffer(A, B, C, D)
ListBuffer(A, B, C, D, E)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...