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

时间:2012-03-08 20:55:55

标签: clojure

我正在尝试清理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"}}
    ]
} }

我的目标是使用“值”键“折叠”那些嵌套映射,删除“foo”assoc,并将值分配给更高一级的映射键(例如,“street”,“zip”,“名称”)。结果数据结构如下所示:

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

这里的任何帮助都会很棒,谢谢!

1 个答案:

答案 0 :(得分: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))