如果嵌套地图只包含{:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5}
等关键字键,我该如何实施flatten-map
,以便(flatten-map {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5} "-")
生成类似{:foo-bar 1 :foo-baz [2 3] :foo-qux-quux 4 :corge 5}
的内容。
我最好的尝试是:
(defn flatten-map
([form separator] (flatten-map form separator nil))
([form separator prefix]
(if (map? form)
(into {} (map (fn [[k v]]
[(keyword (str prefix (name k)))
(flatten-map v separator (str prefix (name k) separator))])
form))
form)))
正如您所见,我无法让flatten-map
仅选择“离开”。
答案 0 :(得分:13)
(defn flatten-map
([form separator]
(into {} (flatten-map form separator nil)))
([form separator pre]
(mapcat (fn [[k v]]
(let [prefix (if pre (str pre separator (name k)) (name k))]
(if (map? v)
(flatten-map v separator prefix)
[[(keyword prefix) v]])))
form)))
你无条件地创建新的键/值对,即使要扩展该值,所以我将map切换到mapcat,以便结果可以“包含”到顶层(这也需要拆分{{1进入表单的顶级版本,因为除了输出的顶层之外我们实际上并不想要任何地图。)
以下是您的示例:
(into {} ...)