tutorial online framework example clojure

online - clojure web framework



Iterato sobre todas las claves del mapa anidado (2)

Dado:

{:o {:i1 1 :i2 {:ii1 4}}}

Me gustaría iterar sobre las teclas del mapa en forma "absoluta" desde la raíz como un vector. Entonces me gustaría:

{ [:o :i1] 1 [:o :i2 :ii1] 4 }

Como el resultado. Básicamente solo obtener los nodos de hoja.


Parece que esto es básicamente un aplanar de las claves anidadas. Esto también parece ser un problema de 4clojure .

Una búsqueda de mapa plano en github produce muchos resultados.

Un ejemplo de implementación:

(defn flatten-map "Flattens the keys of a nested into a map of depth one but with the keys turned into vectors (the paths into the original nested map)." [s] (let [combine-map (fn [k s] (for [[x y] s] {[k x] y}))] (loop [result {}, coll s] (if (empty? coll) result (let [[i j] (first coll)] (recur (into result (combine-map i j)) (rest coll)))))))

Ejemplo

(flatten-map {:OUT {:x 5 :x/A 21 :x/B 33 :y/A 24}}) => {[:OUT :x] 5, [:OUT :x/A] 21, [:OUT :x/B] 33, [:OUT :y/A] 24}

Una versión aún más general de Christoph Grand:

(defn flatten-map "Take a nested map (or a nested collection of key-value pairs) and returns a sequence of key-value pairs where keys are replaced by the result of calling (reduce f pk path) where path is the path to this key through the nested maps." ([f kvs] (flatten-map f nil kvs)) ([f pk kvs] (mapcat (fn [[k v]] (if (map? v) (flatten-map f (f pk k) v) [[(f pk k) v]])) kvs)))

Ejemplo:

(flatten-map conj [] {:OUT {:x 5 :x/A 21 :x/B 33 :y/A 24}}) => ([[:OUT :x] 5] [[:OUT :x/A] 21] [[:OUT :x/B] 33] [[:OUT :y/A] 24])


Una versión que creo que es bastante más agradable, utilizando for lugar de mapcat :

(defn flatten-keys [m] (if (not (map? m)) {[] m} (into {} (for [[k v] m [ks v''] (flatten-keys v)] [(cons k ks) v'']))))

La función es naturalmente recursiva, y el caso base más conveniente para un no mapa es "este valor único, sin keyseq que conduce a él". Para un mapa, puede simplemente llamar flatten-keys en cada valor en el mapa y anteponer su clave a cada segmento de clave del mapa resultante.