Ich habe eine rekursive Funktion, die ich @tailrec
machen möchte, indem ich den inneren rekursiven Teil (countR3
) Elemente zu einer Warteschlange hinzufügen (agenda
ist ein scala.collections.mutable.Queue
). Meine Idee ist, dann den äußeren Teil der Funktion über die Tagesordnung zu legen und die Ergebnisse zusammenzufassen.Gibt es eine elegante Möglichkeit, auf einer wachsenden scala.collections.mutable.Queue foldLeft?
HINWEIS: Diese war ein Hausaufgaben-Problem, also möchte ich nicht den ganzen Code posten; Allerdings war die Durchführung der Tail-rekursive Implementierung nicht Teil der Hausaufgabe.
Hier ist der Teil des Codes ist relevant für meine Frage:
import scala.collection.mutable.Queue
val agenda: Queue[Tuple2[Int, List[Int]]] = Queue()
@tailrec
def countR3(y: Int, x: List[Int]): Int = {
if (y == 0) 1
else if (x.isEmpty) 0
else if …
else {
agenda.enqueue((y - x.head, x))
countR3(y, x.tail)
}
}
⋮
agenda.enqueue((4, List(1, 2)))
val count = agenda.foldLeft(0) {
(count, pair) => {
val mohr = countR3(pair._1, pair._2)
println("count=" + count + " countR3=" + mohr)
count + mohr
}
}
println(agenda.mkString(" + "))
count
Diese fast scheint ... Das Problem zu arbeiten, ist, dass es nicht auf die Tagesordnung gesetzt alle Elemente nicht iterieren, aber es verarbeitet einige von ihnen. Sie können dies in der Ausgabe siehe unten: [. Von den sechs Punkten der endgültigen Tagesordnung, nur die ersten drei verarbeitet wurden]
count=0 countR3=0
count=0 countR3=0
count=0 countR3=0
(4,List(1, 2)) + (3,List(1, 2)) + (2,List(2)) + (2,List(1, 2)) + (1,List(2)) + (0,List(2))
Ich bin im Allgemeinen gut über die Gefahren von mutierenden eine Sammlung, während Sie in Java über iterieren. Aber eine Warteschlange ist ein Pferd von einer anderen Farbe. Natürlich, ich verstehe ich einfach eine dringend notwendige Schleife, wie so schreiben könnte: ein funktionell elegant Weg ist
Das funktioniert sehr gut, aber das ist Scala, erforsche mich, um zu sehen, ob esvar count = 0
while (!agenda.isEmpty) {
val pair = agenda.dequeue()
count += countR3(pair._1, pair._2)
}
.
Irgendwelche Vorschläge?
Nicht gerade idiomatisch, würde ich zustimmen, aber es scheint, wie es das Gesetz des Seins mehr funktionell rein passen würde. Gute Antwort! Und interessanterweise: Agenda.FoldLeft verarbeitete mehr als nur die ursprünglich eingereihten Gegenstände; es schien nicht einfach an einer Kopie der ursprünglichen Warteschlange zu arbeiten. Vielleicht wurde es gestoppt, als der "letzte" Eintrag dazu führte, dass mehr Einträge zur Warteschlange hinzugefügt wurden, oder so ähnlich. –