Wie ich verstehe, gehen und Karte beide eine Funktion auf eine Seq anwenden. (Walk erlaubt auch die Anwendung einer outer
Funktion Post Processing). Was sind jedoch die idiomatischen Fälle der Verwendung eines über dem anderen?Spaziergang vs Karte für die Verarbeitung einer Seq
Antwort
Anwenden einer Funktion auf eine Seq ist die Aufgabe der Karte. Verwenden Sie walk, wenn Sie sowohl durch als auch rekursiv in die gesamte Struktur gehen müssen.
Einige Beispiele von walk
können gefunden werden bei ClojureDocs, ebenfalls erhältlich bei der REPL, z. (user/clojuredocs clojure.walk/postwalk)
. Viele der Beispiele sind pädagogisch und könnten und sollten mit map
oder for
(und manchmal reduce
) in der Praxis gemacht werden.
Der typische Anwendungsfall für eine walk
ist, wenn Sie eine verschachtelte Struktur haben, die Sie rekursiv verarbeiten möchten. Einige Beispiele, wo dies nützlich sein könnte, sind der clojure.walk
Namensraum selbst, z. schau dir (source clojure.walk/keywordize-keys)
an.
Ein weiteres Beispiel, das den Sinn kommt, ist die Interpretation Parse-Bäume [. Verwendung Reißverschlüsse (oder tree-seq
für einige einfachere iterative Fälle) Hinweis, wenn Sie es iterativ oder nach Belieben, bearbeiten wollen]:
(require '[clojure.walk :as w])
(def t [+ [* [- 6 2] [/ 9 3]] [* 2 [+ 7 8]]])
(w/postwalk #(if (and (coll? %) (fn? (first %))) (apply (first %) (next %)) %) t)
;=> 42
Vielleicht nützlich, wenn zB mit einem allowed-fn?
fn?
ersetzen usw. ein edn Ausdruck auszuwerten, anstatt das zu mächtig eval Compiler von Aufrufen:
(eval t) ;=> [#<core$_PLUS_ ... ]
Oops, Formulare Listen, nicht VEC toren:
(def s (w/postwalk #(if (coll? %) (apply list %) %) t))
s ;=> (#<core$_PLUS_ ...)
(eval s) ;=> 42
Ah, bemerken hier eine andere Verwendung eines walk
- die Struktur von verschachtelten Vektoren zu verschachtelten Listen rekursiv ändern.
Ein iteratives Beispiel zu meditieren:
(require '[clojure.walk :as w])
(def s1 (range 8))
s1 ;=> (0 1 2 3 4 5 6 7)
(map inc s1)
;=> (1 2 3 4 5 6 7 8)
(w/postwalk #(if (number? %) (inc %) %) s1)
;=> (1 2 3 4 5 6 7 8)
(def s2 (partition 2 s1))
s2 ;=> ((0 1) (2 3) (4 5) (6 7))
(map (partial map inc) s2)
;=> ((1 2) (3 4) (5 6) (7 8))
(w/postwalk #(if (number? %) (inc %) %) s2)
;=> ((1 2) (3 4) (5 6) (7 8))
(def s3 (partition 2 s2))
s3 ;=> ((0 1) (2 3) (4 5) (6 7))
(map (partial map (partial map inc)) s3)
;=> (((1 2) (3 4)) ((5 6) (7 8)))
(w/postwalk #(if (number? %) (inc %) %) s3)
;=> (((1 2) (3 4)) ((5 6) (7 8)))
(def s4 (partition 2 s3))
s4 ;=> ((((0 1) (2 3)) ((4 5) (6 7))))
(map (partial map (partial map (partial map inc))) s4)
;=> ((((1 2) (3 4)) ((5 6) (7 8))))
(w/postwalk #(if (number? %) (inc %) %) s4)
;=> ((((1 2) (3 4)) ((5 6) (7 8))))
Die Semantik für map
ist im Grunde: die Funktion zu jedem Artikel in der Sammlung anzuwenden und die Ergebnisse lazily in einer Sequenz zurück:
(map inC#{0 1 2}) ;outputs (when realized) (1 2 3)
anzumerken, dass die Eingabe ein Satz war, aber der Ausgang ist eine Sequenz.
Die Semantik für zu Fuß sind im Grunde: eine Sammlung der gleichen Art machen, wobei jedes Element für das Element durch den Wert der inner
Funktion ersetzt wurde, gibt das Ergebnis von outer
auf die neue Kollektion Anwendung:
(walk inc identity #{0 1 2}) ;outputs #{1 2 3}
Wenn Sie den Quellcode für die anderen Funktionen in der Walk-API (http://richhickey.github.com/clojure/clojure.walk-api.html) betrachten, können Sie sehen, wie die Wanderungen auch rekursiv machen (oder nur diese anderen Funktionen verwenden).
Soweit Idiome gehen, bin ich mir nicht sicher. Aber walk
ist komplexer, so dass Sie wahrscheinlich map
in Fällen bleiben sollten, in denen Sie nicht die Semantik benötigen, die walk
bietet.
Ich denke, die andere Antwort verdeutlicht den Unterschied besser. Jedoch +1 für deine Mühe und schätze es! – murtaza52
- 1. scala .seq vs .toSeq
- 2. Iteratorzugriffsleistung für STL-Karte vs. Vektor?
- 3. clojure cons vs conj mit lazy-seq
- 4. Clojure anwenden vs Karte
- 5. Scala Karte vs HashMap
- 6. Funken Mapvalues vs. Karte
- 7. Futures - Karte vs flatmap
- 8. Requirejs: Pfade vs Karte
- 9. Karte getOrDefault VS getOrUseSupplier
- 10. scala Karte zu Seq und map() schlägt plötzlich ohne Fehler
- 11. Statische Erweiterungsmethoden für Seq-Modul
- 12. Scala - Einfangen einer Ausnahme innerhalb einer Karte
- 13. PHP vs C++/Java für intensive Verarbeitung, Speicherdifferenz?
- 14. Xvfb mehrere Displays für die parallele Verarbeitung?
- 15. wie ein Seq seq von Vektoren
- 16. HTML5-Canvas mit Verarbeitung vs. reinem Javascript
- 17. die seq Funktion und Strenge
- 18. Entwurfsmuster für die Verarbeitung mehrerer Nachrichtentypen
- 19. Wie man ein eingezäuntes Feld für den betrunkenen Spaziergang erstellt
- 20. Javascript Filter vs Karte Problem
- 21. Wie funktioniert die Verarbeitung einer SAML-Assertion?
- 22. Konvertieren Seq [Option [T]] zu Seq [T]
- 23. Kein EJB-Empfänger für die Verarbeitung verfügbar
- 24. Sichern von Datenbankschlüsseln für die clientseitige Verarbeitung
- 25. Eigenschaft (ohne zusätzliche Verarbeitung) vs öffentlichen Feld
- 26. Python Multiprocessing: Karte vs map_async
- 27. Karte vs Hashmap in C++
- 28. Schritt-für-Schritt-Beispiel eines Lazy-Seq
- 29. Wann überwindet die parallele Verarbeitung die sequentielle Verarbeitung?
- 30. Zwei Seq-Vergleich in Scala
eine Funktion auf einen seq Anwendung der Job von 'map' ist. Verwenden Sie 'walk', wenn Sie sowohl durch als auch rekursiv in die gesamte Struktur gehen müssen. –
@ A.Webb können Sie es als Antwort posten. Ich möchte es als die Antwort markieren. Ich freue mich auch, wenn Sie auf einige Beispiele von Spaziergang hinweisen können. – murtaza52
Beantwortet meine Frage nicht? – sethev