Clojure:如何使用特定键折叠嵌套的映射?

6

我将尝试在Clojure中清理一些JSON数据。JSON文档中的某些值被封装在带有关联元数据(不再需要)的对象中。我从类似以下的JSON文档开始:

{ "household": {
    "address": {
        "street": { "value": "123 Fire Ln", "foo": "bar1" },
        "zip": { "value": "01234", "foo": "bar2" }
    },
    "persons": [
        {
            "id": "0001",
            "name": { "value": "John Smith", "foo": "bar3" }
        },
        {
            "id": "0002",
            "name": { "value": "Jane Smith", "foo": "bar4" }
        }
    ]
} }

使用Cheshire,我解析了这个JSON并得到了以下数据结构:
{ "household" {
    "address" {
        "street" {"value" "123 Fire Ln", "foo" "bar1"},
        "zip" {"value" "01234", "foo" "bar2"}
    },
    "persons" [
        {"id" "0001", "name" {"value" "John Smith", "foo" "bar3"}}
        {"id" "0002", "name" {"value" "Jane Smith", "foo" "bar4"}}
    ]
} }

我的目标是将那些带有“value”键的嵌套映射“折叠起来”,删除“foo”关联,并将值分配给更高层级的映射键(例如“street”,“zip”,“name”)。 最终的数据结构如下所示:

{ "household" {
    "address" {
        "street" "123 Fire Ln",
        "zip" "01234"
    },
    "persons" [
        {"id" "0001", "name" "John Smith"}
        {"id" "0002", "name" "Jane Smith"}
    ]
} }

任何帮助都会很棒,谢谢!
1个回答

9
听起来需要使用 clojure.walk/postwalk 这个函数!
(defn collapse [obj]
  (postwalk (fn [obj]
              (or (and (map? obj)
                       (get obj "value"))
                  obj))
            obj))

您可以将此缩短,因为get可以使用非映射对象(它只返回nil),但我认为第一个版本更加清晰明了。
(defn collapse [obj]
  (postwalk #(get % "value" %) obj))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接