2016-06-22 17 views
2

Ich habe eine Sequenz wie:Scala Sequenz zu einer Sequenz von Sequenz

Seq(1,2,3) 

Ich versuche, eine Sequenz einer Sequenz zu erhalten, die wie folgt aussehen:

Seq(Seq(1), Seq(1,2), Seq(1,2,3)) 

Hier ist, was ich kam mit:

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) 
    } 

Wie erwartet, ich bin ein NoSuchElementException auf dem Platz treffen, wo ich xs.head tun. Ich bin sicher, dass es etwas geben muss, dass ich falsch mache! Vielleicht bin ich vermisst. Dieses gibt mir nicht das erwartete Ergebnis, aber das war nur ein Versuch!

Edit: Das ursprüngliche Ziel war es Split ein String, der in so kommt:

"1.2.3" auf eine Sequenz von Zeichenfolgen als Seq ("1), Seq (" 1.2 "), Seq (" 1.2.3")

zu erreichen Dies bin ich zuerst auf der Grundlage der. Zeichen, über die resultierende Sequenz gehen und sie wieder mit dem verketten. Charakter.

+1

Mögliches Duplikat [Scala: Jede vordefinierte Funktionsliste iterieren (0), dann Liste (0, 1), dann Liste (0, 1, 2), etc.?](http:// stackoverflow.com/questions/33691530/scala-any-predefined-function-to-iterate-over-list0-then-list0-1-then-li) –

Antwort

0

Fast fertig:

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) 
    } 
4

Sie können auch dies erreichen (nicht zu effizient, aber prägnant) mit 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: Pro Frage Update, eine ähnliche Art und Weise zu finde alle Präfixe eines Strings bis zu einem "." Begrenzer wäre, nur den String als Folge von Chars zu behandeln:

"1.2.3".inits.filter(s => s.nonEmpty && !s.endsWith(".")).toList.reverse 
+0

Cool! Warum ist das effizient? – sparkr

+1

es durchquert die Eingabe zweimal - einmal, um 'inits' Ergebnis und einmal um es umzukehren. Dies ist natürlich nur für große Listen von Bedeutung, für kurze ist dies vernachlässigbar. –

+0

Ich denke, ich mag das wie in meinem Seq, ich werde nie mehr als 3 Elemente haben! – sparkr

0

Wenn Ihr Seq keine Duplikate haben und ist bestellt, die Sie tun können:

val yourSeq = Seq(1,2,3) 
yourSeq.map(e => Seq(yourSeq.takeWhile(_ <= e))).flatten 
6
Seq(1,2,3).scanLeft(Seq[Int]())(_ :+ _).tail 

Wenn die Liste länger, an das Ende eines Seq in scanLeft anhängen könnte zu teuer werden. In diesem Fall könnten Sie einer Liste vorangehen und einen umgekehrten Schritt hinzufügen oder einen veränderbaren Builder (wie ListBuffer) verwenden.

3
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)) 
+2

+1, und eine andere Variante im selben Geist mit' Indizes': 'input.indices.map (i => input.take (i + 1))' –