Reputation: 15345
I have a Sequence as:
Seq(1,2,3)
I'm trying to get a Sequence of a Sequence that would look like this:
Seq(Seq(1), Seq(1,2), Seq(1,2,3))
Here is what I came up with:
def pop(acc: Seq[Seq[Int]], elems: Seq[Int]): Seq[Int] = elems match {
case Nil => acc.flatten
case x :: xs =>
pop(acc ++ Seq(Seq(x, xs.head)), xs.tail)
}
As expected, I'm hitting a NoSuchElementException on the place where I do xs.head. I'm sure there must be something that I"m doing wrong! May be I'm missing. This one does not give me the expected result, but this was just a try!
Edit: The original goal was to split a String that comes in as:
"1.2.3" to a Sequence of Strings as Seq("1), Seq("1.2"), Seq("1.2.3")
To achieve this, I'm first splitting based on the . character, going over the resulting Sequence and concatenating them again with the . character.
Upvotes: 3
Views: 2638
Reputation: 37822
You can also achieve this (not too efficiently, but concisely) using inits
:
scala> Seq(1,2,3).inits.toList.reverse.tail
res0: List[Seq[Int]] = List(List(1), List(1, 2), List(1, 2, 3))
EDIT: Per question update, a similar way to find all prefixes of a String up to a "." delimiter would be to just treat the String as a sequence of Chars:
"1.2.3".inits.filter(s => s.nonEmpty && !s.endsWith(".")).toList.reverse
Upvotes: 5
Reputation: 54574
Seq(1,2,3).scanLeft(Seq[Int]())(_ :+ _).tail
If the list is longer, appending to the end of a Seq
in scanLeft
might become too expensive. In that case you could prepend to a List, and add a reverse step, or use some mutable builder (like ListBuffer
).
Upvotes: 7
Reputation: 4471
val input = Seq(1,2,3)
val result = (1 to input.length).map(input.take).toList // List(List(1), List(1, 2), List(1, 2, 3))
Upvotes: 4
Reputation: 1515
If your Seq
does not have duplicates and is ordered, you can do:
val yourSeq = Seq(1,2,3)
yourSeq.map(e => Seq(yourSeq.takeWhile(_ <= e))).flatten
Upvotes: 0
Reputation: 15345
Almost there:
def pop(acc: Seq[Seq[Int]], elems: Seq[Int]): Seq[Seq[Int]] = elems match {
case Nil => acc
case x :: xs =>
if (acc.isEmpty)
pop(Seq(Seq(x)), xs)
else
pop(acc ++ Seq(acc.last ++ Seq(x)), xs)
}
Upvotes: 0