所以我有这个数据结构:
(def params
{:site1
{:index-element
{:date "2012-10-10"
:title "Hello"}
:subpage-element
{:time "9:00"
:location "Toronto"}}
:site2 …})
我想将其更改为更扁平的数据结构
(def new-params
{1
{:name :site1
:date ["2012-10-10" :index-element]
:title ["Hello" :index-element]
:time ["9:00" :subpage-element]
:location ["Toronto" :subpage-element]}
2 …})
要获得我想要的结果:
(mapv #(-> params % :index-element vals)
(keys params))
我如何使用new-params获得相同的结果?
答案 0 :(得分:4)
以下是三种方式:
;;; 1.
(reduce-kv (fn [res siteno m]
(->> (vals m)
(filter #(and (vector? %)
(identical? :index-element (peek %))))
(map first)
(conj res)))
[]
new-params)
;;; 2.
(->> new-params
(vals)
(map vals)
(map (partial filter #(and (vector? %)
(identical? :index-element (peek %)))))
(mapv (partial map first)))
;;; 3. (better than 2., but only for Clojure >= 1.5)
(require '[clojure.core.reducers :as r])
(->> new-params
(vals)
(r/map vals)
(r/map (partial filter #(and (vector? %)
(identical? :index-element (peek %)))))
(r/map (partial map first))
(into []))
切换到mapv
(在1.中的匿名函数中,在2.& 3中的最后partial
中)以获取向量的向量而不是惰性seq的向量(和从而使内部集合的构建变得非常惰性 - 这可能很有意义。)
原始数据结构实际上更适合这种访问;没有避免使用更平坦的地图进行线性搜索。这可能是性能问题,具体取决于访问模式和实际数据。
答案 1 :(得分:3)
一个选项是使用for
(在恕我直言中使其更具可读性):
(->> (for [[i site] new-params]
(for [ [s-k s-v] site
:when (not= s-k :name)
:let [[k [v v-k]] [s-k s-v]]
:when (= v-k :index-element)]
v))
(into []))