通过连接键来平面化地图 [英] 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}
。
我最好的尝试是:
(defn flatten-map
([form separator](flatten-map form separator nil))
(到{}(map(fn [[kv]]
[(关键字(str prefix(name k)))
(flat prefix-分隔符))])
形式))
形式)))
你可以看到我不能得到 flatten-map
只选择叶子。
(defn flatten-map
/ pre>
(表单分隔符)
(到{}(flatten-map form separator nil)))
([form separator]
(mapcat(fn [[kv]]
(let [prefix(if pre(str pre separator(name k))(name k))]
(if(map? v)
(flatten-map v separator prefix)
[[(关键字前缀)v]])))
form)))
您无条件创建新的键/值对,即使该值被扩展,因此我将映射切换到mapcat,以便结果可以 进入顶层(这也需要将
(into {} ...)
分成顶级版本的表单,因为我们实际上不想要任何地图
以下是您的示例的工作原理:
user> (flatten-map {:foo {:bar 1:baz [2 3]:qux {:quux 4}}:corge 5} - )
{:foo-bar 1,:foo-qux- 4,:foo-baz [2 3],: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 implementflatten-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}
.My best attempt is:
(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)))
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)))
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屋!