假设我有一个这样的map(m):
(def m {:a 1 :b 2 :c {:d 3 :e 4} :e { ... } ....})
Run Code Online (Sandbox Code Playgroud)
我想创建一个新的地图只含有:a,:b并:d从m,即结果应该是:
{:a 1 :b 2 :d 3}
Run Code Online (Sandbox Code Playgroud)
我知道我可以select-keys轻松地使用:a和:b:
(select-keys m [:a :b])
Run Code Online (Sandbox Code Playgroud)
但是有什么好办法:d呢?我正在寻找这样的东西:
(select-keys* m [:a :b [:c :d]])
Run Code Online (Sandbox Code Playgroud)
Clojure中是否存在这样的功能或推荐的方法是什么?
在纯Clojure中,我会这样做:
(defn select-keys* [m paths]
(into {} (map (fn [p]
[(last p) (get-in m p)]))
paths))
(select-keys* m [[:a] [:b] [:c :d]]) ;;=> {:a 1, :b 2, :d 3}
Run Code Online (Sandbox Code Playgroud)
我更喜欢保持路径的类型是规则的,因此所有路径都有一系列键.在clojure.spec这将读为
(s/def ::nested-map (s/map-of keyword?
(s/or :num number? :map ::nested-map)))
(s/def ::path (s/coll-of keyword?))
(s/fdef select-keys*
:args (s/cat :m ::nested-map
:paths (s/coll-of ::path)))
Run Code Online (Sandbox Code Playgroud)