通过加入键来展平地图 [英] Flattening a map by join the keys
问题描述
给定一个只有关键字键的嵌套映射,例如 {: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}
.
Given a nested map with only keyword keys such as {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5}
, how can I implement flatten-map
so that (flatten-map {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5} "-")
produces something like {: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
仅选择叶子".
As you can see I can't get flatten-map
to select only the "leaves".
推荐答案
(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,以便结果可以包含"到顶层(这也需要拆分 (进入 {} ...)
进入表单的顶级版本,因为除了输出的顶级之外,我们实际上并不想要任何地图.
you were unconditionally creating new key / value pairs, even when the value was to be expanded, so I switched map to mapcat so that a result could be "subsumed" into the top level (this also required splitting the (into {} ...)
into the top level version of the form, since we don't actually want any maps anywhere but the top level of the output).
以下是它如何与您的示例配合使用:
Here is how it works with your example:
user> (flatten-map {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5} "-")
{:foo-bar 1, :foo-qux-quux 4, :foo-baz [2 3], :corge 5}
这篇关于通过加入键来展平地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!