Ich kämpfe einfach funktionellen Weg zu finden, zu transformierenWie summiere ich die Liste der ganzen Zahlen und speichere jeden Schritt in der neuen Liste?
val ints = List(1, 2, 3, 4, 5) into List(1, 3, 6, 10, 15)
Wie kann es geschehen?
Ich kämpfe einfach funktionellen Weg zu finden, zu transformierenWie summiere ich die Liste der ganzen Zahlen und speichere jeden Schritt in der neuen Liste?
val ints = List(1, 2, 3, 4, 5) into List(1, 3, 6, 10, 15)
Wie kann es geschehen?
Diese Operation wird prefix sum, cumulative sum, or inclusive scan genannt, die verallgemeinerte Funktion höherer Ordnung wird normalerweise scan
genannt. Scala bietet scan
als Teil seiner Sammlungen Bibliothek:
ints.scan(0)(_ + _).tail
Sie foldLeft
verwenden können, wie folgt:
scala> List(1,2,3,4,5).foldLeft(List.empty[Int]) { case (acc, next) =>
| acc :+ next + acc.lastOption.getOrElse(0)
| }
res6: List[Int] = List(1, 3, 6, 10, 15)
In der Teilfunktion (acc, next)
ist acc
die aktuell akkumulierten Liste, die als List.empty[Int]
beginnt, und next
ist der nächste Wert in der bereitgestellten Liste, mit 1
Start .
OP sagte "* simple * -funktional :) –
Einfachheit ist relativ: P – Eric
ints.foldLeft(List[Int]())((acc,elem)=>elem+acc.headOption.getOrElse(0)::acc)
Dies führt zu einer umgekehrten lis t, so müssten Sie am Ende '.reverse' aufrufen. – Eric
Ups, ich habe vergessen, du hast Recht. With: + es wäre besser – Chobeat
@Chobeat nein würde es nicht, weil der Anhang wäre O (N), wie würde die benötigte lastOption. Wenn die gesamte Operation O (N * 2) –
Oh, gehen, eine andere Art und Weise die Katze Haut:
ints.drop(1).foldLeft(List(ints.head))((acc,elem)=>elem+acc.head::acc).reverse
Dank Lee Antwort geändert ich es
ints.tail.scan(ints.head)(_ + _)
Etwas länger, aber es behandelt das erste Element als Anfangszustand.
mit 'ints.drop (1) ...' erstellt wird, wird keine Ausnahme ausgelöst, wenn 'ints' leer ist. - –
Ich denke, dass @Lee Antworten ist viel einfacher zu lesen –
Dies ist auch anfällig für Ausnahmen, wenn die Sammlung leer ist. – stefanobaghino
Kurz und einfach wie ich gehofft, obwohl Scan-Aufruf mit Standard-Anfangszustand als erstes Element der Liste wäre noch besser. – MaciejF
Wie ints.scan (_ + _) – MaciejF
Leider glaube ich nicht, dass es ein Äquivalent zu [Haskells 'scanl1'] gibt (https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:scanl1) wie es mit ['fold'] ist (http://scala-lang.org/api/current/scala/collection/Seq.html#fold [A1>: A] (z: A1) (op: (A1 , A1) => A1): A1)/['reduzieren'] (http://scala-lang.org/api/current/scala/collection/Seq.html#reduce [A1>: A] (op :(A1, A1) => A1): A1) –