Wie alle anderen schon gesagt haben, ist die Verwendung von Listen wirklich keine gute Idee, wenn Sie so etwas tun müssen. Random Access ist, wofür Vektoren gemacht werden. assoc-in
macht das effizient. Mit Listen können Sie nicht davon abkommen, sich in die Unterlisten zurückzuversetzen und die meisten von ihnen durch geänderte Versionen von sich selbst bis ganz nach oben zu ersetzen.
Dieser Code wird es tun, wenn auch ineffizient und ungeschickt. Entlehnung aus Dermatithias:
%Vor%Verwendung:
%Vor% Sie erhalten IndexOutOfBoundsException
, wenn Sie n
größer als die Länge einer Unterliste angeben. Es ist auch nicht tail-rekursiv. Es ist auch nicht idiomatisch, weil guter Clojure-Code davor zurückschreckt, Listen für alles zu verwenden. Es ist schrecklich. Ich würde wahrscheinlich veränderbare Java-Arrays verwenden, bevor ich das verwendete. Ich denke, Sie haben die Idee.
Gründe, warum Listen in diesem Fall schlechter sind als Vektoren:
%Vor% Sie müssen auch assoc-in
nicht selbst schreiben, es existiert bereits. Sehen Sie sich die Implementierung für assoc-in
an. es ist einfach und unkompliziert (im Vergleich zur Listenversion) dank Vektoren, die einen effizienten und einfachen Direktzugriff nach Index über get
ermöglichen.
Sie müssen auch keine Vektoren angeben, wie Sie Listen zitieren müssen. Listen in Clojure bedeuten stark "Ich rufe hier eine Funktion oder ein Makro auf".
Vektoren (und Karten, Mengen usw.) können über seq
s durchlaufen werden. Sie können Vektoren auf Listen-ähnliche Weise transparent verwenden, also warum nicht Vektoren verwenden und das Beste aus beiden Welten haben?
Vektoren heben sich auch visuell ab. Clojure Code ist weniger von einem riesigen Haufen von Parens als andere Lisps dank der weit verbreiteten Verwendung von []
und {}
. Manche Leute finden das nervig, ich finde es leichter lesbar. (Meine Editor-Syntax hebt ()
, []
und {}
anders hervor, was noch mehr hilft.)
In einigen Fällen würde ich eine Liste für Daten verwenden:
lazy-seq
Für die einfachen Fälle gibt Ihnen eine rekursive Substitutionsfunktion genau das, was Sie benötigen, ohne viel zusätzliche Komplexität. Wenn die Dinge ein wenig komplexer werden, ist es an der Zeit, offene Clojure-Builds in Zipper Funktionen zu knacken: "Clojure beinhaltet rein funktionales, generisches Tree Walking und Bearbeiten , mit einer Technik namens Zipper (im Namespace-Zip). "
angepasst an das Beispiel in Ссылка
%Vor%diese arbeiten mit verschachtelten allem (seq'able) sogar xmls
Es beantwortet Ihre Frage nicht, aber wenn Sie Vektoren anstelle von Listen haben:
%Vor%Also möglichst Listen zugunsten von Vektoren für das bessere Zugriffsverhalten vermeiden. Wenn Sie mit Lazy-Seq aus verschiedenen Quellen arbeiten müssen, ist dies natürlich kein großer Ratschlag ...
Sie können diese Funktion verwenden und an Ihre Bedürfnisse anpassen (verschachtelte Listen):
%Vor%Ein einfältiger Vorschlag aus der Erdnuss-Galerie:
assoc
; Dies könnte etwas Leistung verschwenden; Aber wenn dies eine leistungsabhängige Operation wäre, würden Sie mit Vektoren arbeiten.
Tags und Links clojure