Clojure: Wie wird ein Element in einer verschachtelten Liste ersetzt?

7

Ich habe diese tief verschachtelte Liste (Liste von Listen) und ich möchte ein einzelnes beliebiges Element in der Liste ersetzen. Wie kann ich das machen ? (Das integrierte Ersetzen kann viele Vorkommen ersetzen, während ich nur ein Element ersetzen muss.)

    
GabiMe 07.12.2009, 11:38
quelle

5 Antworten

9

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.

Bearbeiten

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:

  1. Wenn ich eine geordnete Datenstruktur habe, die von vorne wachsen muss, brauche ich keinen zufälligen Zugriff auf
  2. Aufbau einer seq "von Hand", wie via lazy-seq
  3. Schreiben eines Makros, das Code als Daten zurückgeben muss
Brian Carper 07.12.2009, 18:32
quelle
6

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

    
Arthur Ulfeldt 07.12.2009 18:56
quelle
5

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 ...

    
kotarak 07.12.2009 14:58
quelle
0

Sie können diese Funktion verwenden und an Ihre Bedürfnisse anpassen (verschachtelte Listen):

%Vor%     
dermatthias 07.12.2009 14:12
quelle
0

Ein einfältiger Vorschlag aus der Erdnuss-Galerie:

  • Kopiere die innere Liste in einen Vektor;
  • Geige die Elemente dieses Vektors nach dem Zufallsprinzip und nach Herzenslust mit assoc ;
  • kopiere den Vektor zurück in eine Liste;
  • ersetzt die verschachtelte Liste in der äußeren Liste.

Dies könnte etwas Leistung verschwenden; Aber wenn dies eine leistungsabhängige Operation wäre, würden Sie mit Vektoren arbeiten.

    
Carl Smotricz 07.12.2009 21:55
quelle

Tags und Links