Ich bin teilweise auf clojure.walk
für diese Art von Jobs. Die Grundidee besteht darin, Funktionen zu erstellen, die die gewünschte Ersetzung ausführen, wenn sie einen Wert erhalten, der ersetzt werden soll. Andernfalls wird das Argument zurückgegeben. Dann übergeben Sie diese Funktion und eine Struktur an postwalk
(oder prewalk
) und es geht die Datenstruktur für Sie, wobei jeder Wert durch den Rückgabewert der Funktion ersetzt wird.
(ns replace-keywords
(:require [clojure.walk :refer [postwalk]]
[clojure.string :refer [join]]))
(defn dash-keyword [k]
(when (keyword? k)
(->> k
str
(map (some-fn {\. \-} identity))
rest
join
keyword)))
(dash-keyword :foo.bar/baz)
;; => :foo-bar/baz
(defonce nested [ {:my-dotted/namespace "FOO"}
{:my-nested/vec [ {:another-dotted/namespace "BAR"
:and-another/one "FIZ"} ]}])
(postwalk (some-fn dash-keyword identity) nested)
;; =>[{:my-dotted/namespace "FOO"}
;; {:my-nested/vec [{:another-dotted/namespace "BAR",
;; :and-another/one "FIZ"}]}]
Zweimal hier verwende ich die Kombination von some-fn
mit einer Funktion, die einen Ersatz oder nil
zurückzugibt, was eine nette Art und Weise sein kann mehrere „Ersetzungsregeln“ zu kombinieren - wenn keine des früheren Feuers dann identity
sein Der erste, der einen Wert ungleich nil
zurückgibt und das Argument wird nicht geändert.
(require '[clojure.string :as str])
(defn dot->dash [maps]
(mapv #(into {} (for [[k v] %]
[(keyword (str/replace (namespace k) "." "-") (name k))
(if (vector? v) (dot->dash v) v)]))
maps))
Beispiel:
Dank, das absolut, was ich brauche - ich 'gehen' erinnern. – Zuriar