Clojure - 计算嵌套映射中嵌套键的出现次数?
Clojure - Count occurences of nested key in nested map?
我有一个这样的嵌套地图:
{:A {:B {:A {:B {:A {:B 0}}}}}}
我想计算 [:A :B] 对的出现次数,所以在上面的例子中,结果是 3。
我最初的想法是使用clojure.walk/postwalk
遍历地图并增加一个计数器。
是否有更优化的方法来实现这一点?
因为是嵌套map,我务实的想法是递归遍历并计数:
(defn do-count [m]
(loop [m m
counter 0]
(if-let [m* (get-in m [:A :B])]
(recur m* (inc counter))
counter)))
(do-count {:A {:B {:A {:B {:A {:B 0}}}}}}) ;==> 3
我建议编写一个函数,将深度嵌套的地图转换为由路径作为键控的平面地图
(defn flatten-map
"unwind deeply nested map into map of paths and vals"
([m] (into {} (flatten-map [] m)))
([path m]
(if (map? m)
(mapcat (fn [[k v]]
(flatten-map (conj path k) v))
m)
[[path m]])))
你可以像这样使用它来计算相邻的 [:a :b] 键
(->> {:A {:B {:A {:B {:A {:B 0}}}}}}
flatten-map
keys
(mapcat #(partition 2 1 %))
(filter #(= [:A :B] %))
count)
tree-seq
在这种情况下效果很好:
(defn count-ab [data]
(->> data
(tree-seq coll? seq)
(keep #(get-in % [:A :B]))
count))
user> (def data {:A {:B {:A {:B {:A {:B 0}}}}}})
#'user/data
user> (count-ab data)
3
user> (def data-1 {:A {:B {:C {:A {:B {:A {:B 0}}}}}}})
#'user/data-1
user> (count-ab data-1)
3
user> (def data-2 {:A {:X {:A {:B 100}}
:B {:C {:A {:B {:A {:B 0}}}}}}})
#'user/data-2
user> (count-ab data-2)
4
我有一个这样的嵌套地图:
{:A {:B {:A {:B {:A {:B 0}}}}}}
我想计算 [:A :B] 对的出现次数,所以在上面的例子中,结果是 3。
我最初的想法是使用clojure.walk/postwalk
遍历地图并增加一个计数器。
是否有更优化的方法来实现这一点?
因为是嵌套map,我务实的想法是递归遍历并计数:
(defn do-count [m]
(loop [m m
counter 0]
(if-let [m* (get-in m [:A :B])]
(recur m* (inc counter))
counter)))
(do-count {:A {:B {:A {:B {:A {:B 0}}}}}}) ;==> 3
我建议编写一个函数,将深度嵌套的地图转换为由路径作为键控的平面地图
(defn flatten-map
"unwind deeply nested map into map of paths and vals"
([m] (into {} (flatten-map [] m)))
([path m]
(if (map? m)
(mapcat (fn [[k v]]
(flatten-map (conj path k) v))
m)
[[path m]])))
你可以像这样使用它来计算相邻的 [:a :b] 键
(->> {:A {:B {:A {:B {:A {:B 0}}}}}}
flatten-map
keys
(mapcat #(partition 2 1 %))
(filter #(= [:A :B] %))
count)
tree-seq
在这种情况下效果很好:
(defn count-ab [data]
(->> data
(tree-seq coll? seq)
(keep #(get-in % [:A :B]))
count))
user> (def data {:A {:B {:A {:B {:A {:B 0}}}}}})
#'user/data
user> (count-ab data)
3
user> (def data-1 {:A {:B {:C {:A {:B {:A {:B 0}}}}}}})
#'user/data-1
user> (count-ab data-1)
3
user> (def data-2 {:A {:X {:A {:B 100}}
:B {:C {:A {:B {:A {:B 0}}}}}}})
#'user/data-2
user> (count-ab data-2)
4