通过加入键来展平地图

时间:2013-07-27 19:59:12

标签: clojure

如果嵌套地图只包含{: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仅选择“离开”。

1 个答案:

答案 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 {} ...)