Scala: Any predefined function to iterate over lis

2019-08-08 19:37发布

问题:

I want to iterate over a scala list in an incremental way, i.e. the first pass should yield the head, the second the first 2 elements, the next the first 3, etc...

I can code this myself as a recursive function, but does a pre-existing function exist for this in the standard library?

回答1:

You can use the .inits method to get there, albeit there may be performance issues for a large list (I haven't played around with making this lazy):

scala> val data = List(0,1,2,3,4)
data: List[Int] = List(0, 1, 2, 3, 4)

scala> data.inits.toList.reverse.flatten
res2: List[Int] = List(0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4)


回答2:

You can use the take like so:

 scala> val myList = 1 to 10 toList
 myList: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

 scala> for(cnt <- myList.indices) yield myList.take(cnt+1)

 res1: scala.collection.immutable.IndexedSeq[List[Int]] = Vector(List(1), List(1, 2), List(1, 2, 3), List(1, 2, 3, 4), List(1, 2, 3, 4, 5), List(1, 2, 3, 4, 5, 6), List(1, 2, 3, 4, 5, 6, 7), List(1, 2, 3, 4, 5, 6, 7, 8), List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))


回答3:

OK, since I've whined enough, here's an iterator version that tries reasonably hard to not waste space or compute more than is needed at at one point:

  class stini[A](xs: List[A]) extends Iterator[List[A]] {
    var ys: List[A] = Nil
    var remaining = xs

    def hasNext = remaining.nonEmpty
    def next = {
      val e = remaining.head
      remaining = remaining.tail
      ys = e :: ys
      ys.reverse
    }
  }

  val it = new stini(List(1, 2, 3, 4))

  it.toList
  //> List[List[Int]] = 
  //      List(List(1), List(1, 2), List(1, 2, 3), List(1, 2, 3, 4))


回答4:

Try: for((x, i) <- l.view.zipWithIndex) println(l.take(i + 1))

if you need something side-effected (I just did println to give you an example)



标签: scala