很抱歉,如果这个问题已经在其他地方得到了回答,但我似乎找不到一个与我正在寻找的模式相匹配的示例。我可能还没有完全理解递归的幽灵路径。
如果我有数据(显式地使用嵌套向量):
{:a "1" :b "2" :c [ {:a "3" :b "4"} {:a "5" :b "6"} ]}
我想将keyword函数应用于所有键为:a的值,结果为:
{:a :1 :b "2" :c [ {:a :3 :b "4"} {:a :5 :b "6"} ]}
最后,我希望它递归到任意深度,并处理向量的情况。
我读过https://github.com/nathanmarz/specter/wiki/Using-Specter-Recursively,但我肯定漏掉了一些关键的东西。
感谢为我指明正确方向的人!
发布于 2019-01-09 14:04:58
(use '[com.rpl.specter])
(let [input {:a "1" :b "2" :c [{:a "3" :b "4"} {:a "5" :b "6"}]}
desired-output {:a :1 :b "2" :c [{:a :3 :b "4"} {:a :5 :b "6"}]}
FIND-KEYS (recursive-path [] p (cond-path map? (continue-then-stay [MAP-VALS p])
vector? [ALL p]
STAY))]
(clojure.test/is
(= (transform [FIND-KEYS (must :a)] keyword input)
desired-output)))发布于 2019-01-09 09:55:37
不是Specter解决方案,但可以通过clojure.walk/postwalk轻松完成
(ns demo.core
(:require
[clojure.walk :as walk] ))
(def data {:a "1" :b "2" :c [{:a "3" :b "4"} {:a #{7 8 9} :b "6"}]})
(def desired {:a :1 :b "2" :c [{:a :3 :b "4"} {:a #{7 8 9} :b "6"}]})
(defn transform
[form]
(if (map-entry? form)
(let [[key val] form]
(if (and
(= :a key)
(string? val))
[key (keyword val)] ; can return either a 2-vector
{key val})) ; or a map here
form))
(walk/postwalk transform data) =>
{:a :1, :b "2", :c [{:a :3, :b "4"} {:a #{7 9 8}, :b "6"}]}我甚至为其中一个:a值添加了一个非字符串,以使其更加复杂。
https://stackoverflow.com/questions/54102091
复制相似问题