Ich hatte diese Frage auf Javaranch gestellt, konnte aber nicht Ich bekomme dort eine Antwort. Also posten Sie es auch hier:
Ich habe diese spezielle Anforderung, bei der das Inkrement in der Schleifenvariable durch Multiplikation mit 5 nach jeder Iteration erfolgen soll. In Java könnten wir es so implementieren:
%Vor%In scala habe ich den folgenden Code versucht -
%Vor%Aber es druckt die folgende Ausgabe: 1 1 6 2 11 3 16 4 21 5 26 6 31 7 36 8 .... ....
Es wird immer um 5 erhöht. Wie kann ich das Inkrement tatsächlich um 5 multiplizieren, anstatt es hinzuzufügen?
Lassen Sie uns zuerst das Problem erklären. Dieser Code:
%Vor%entspricht dem:
%Vor% Wenn Sie also j
mutieren, wurden increment
und byRange
bereits berechnet. Und Range
ist ein unveränderliches Objekt - Sie können es nicht ändern. Selbst wenn Sie neue Bereiche erstellt haben, während Sie foreach
ausgeführt haben, wäre das Objekt, das foreach
ausführt, immer noch dasselbe.
Nun zur Lösung. Einfach gesagt, Range
ist nicht ausreichend für Ihre Bedürfnisse. Sie wollen eine geometrische Progression, keine arithmetische. Für mich (und so gut wie alle anderen, die es zu beantworten scheinen) wäre die natürliche Lösung, ein Stream
oder Iterator
zu verwenden, das mit iterate
erstellt wurde, das den nächsten Wert basierend auf dem vorherigen berechnet.
BEARBEITEN: Über Stream vs Iterator
Diese unendlichen Sammlungen sind möglich, weil die Sammlung nicht vorberechnet ist. Bei einem Wie ich bereits erwähnt habe, sind dies jedoch sehr unterschiedliche Sammlungen in anderer Hinsicht. So (1) In der Tat ist (2) Obwohl Stream
und Iterator
sind sehr unterschiedliche Datenstrukturen, die die Eigenschaft teilen, nicht-strikt zu sein. Diese Eigenschaft ermöglicht, dass iterate
überhaupt existiert, da diese Methode eine unendliche Sammlung 1 erstellt, aus der takeWhile
ein neues 2 List
werden alle Elemente innerhalb der Liste tatsächlich zu dem Zeitpunkt gespeichert, an dem die Liste erstellt wurde. Bei den obigen Beispielen ist jedoch nur das erste Element jeder Sammlung im voraus bekannt. Alle anderen werden nur bei Bedarf berechnet. Stream
ist eine immutable
Datenstruktur. Zum Beispiel können Sie den Inhalt von s2
so oft drucken, wie Sie möchten, und es wird jedes Mal dieselbe Ausgabe angezeigt. Auf der anderen Seite ist Iterator
eine veränderbare Datenstruktur. Sobald Sie einen Wert verwendet haben, ist dieser Wert für immer verschwunden. Drucke den Inhalt von i2
zweimal und es ist das zweite Mal leer: Stream
hingegen ist eine lazy
-Auflistung. Sobald ein Wert berechnet wurde, wird bleiben berechnet, anstatt jedes Mal verworfen oder neu berechnet zu werden. Siehe unten ein Beispiel für dieses Verhalten in Aktion: Stream
kann tatsächlich den Speicher füllen, wenn man nicht vorsichtig ist, während Iterator
konstanten Platz einnimmt. Auf der anderen Seite kann man wegen seiner Nebenwirkungen von Iterator
überrascht sein. Iterator
überhaupt keine Sammlung, obwohl sie viele der Methoden teilt, die von Sammlungen zur Verfügung gestellt werden. Auf der anderen Seite, von der Problembeschreibung, die Sie gaben, sind Sie nicht wirklich daran interessiert, eine Sammlung von Zahlen zu haben, nur indem Sie sie durchlaufen. takeWhile
tatsächlich ein neues Iterator
auf Scala 2.8.0 erstellt, wird dieser neue Iterator immer noch mit dem alten verknüpft und Änderungen in einem haben Nebenwirkungen auf dem anderen. Dies ist Gegenstand von Diskussionen und könnte in Zukunft wirklich unabhängig sein.
In einem funktionelleren Stil:
%Vor%Und mit mehr syntaktischem Zucker:
%Vor%Vielleicht würde eine einfache While-Schleife tun?
%Vor%oder wenn Sie auch die Anzahl der Iterationen
drucken möchten %Vor%Es sieht so aus, als ob euch die Funktion gefällt. Wie wäre es also mit einer rekursiven Lösung ?
%Vor%Update : Danke, dass du den Fehler entdeckt hast ... es sollte natürlich Macht sein, nicht zu multiplizieren:
Ärgerlich scheint es keine Ganzzahl pow
Funktion in der Standardbibliothek zu geben!
Versuchen Sie Folgendes:
%Vor%Oder wenn Sie es direkt verwenden möchten:
%Vor%und mit den Indizes:
%Vor%erzeugt einen Vektor mit i, j in umgekehrter Reihenfolge.