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

mrs*_*cey 5 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" }
        }
    ]
} }
Run Code Online (Sandbox Code Playgroud)

使用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"}}
    ]
} }
Run Code Online (Sandbox Code Playgroud)

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

{ "household" {
    "address" {
        "street" "123 Fire Ln",
        "zip" "01234"
    },
    "persons" [
        {"id" "0001", "name" "John Smith"}
        {"id" "0002", "name" "Jane Smith"}
    ]
} }
Run Code Online (Sandbox Code Playgroud)

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

ama*_*loy 9

听起来像个工作clojure.walk/postwalk!

(defn collapse [obj]
  (postwalk (fn [obj]
              (or (and (map? obj)
                       (get obj "value"))
                  obj))
            obj))
Run Code Online (Sandbox Code Playgroud)

你实际上可以大大缩短这个,因为get它愿意处理非地图对象(它只是返回nil),但我认为第一版中发生的事情要清楚得多.

(defn collapse [obj]
  (postwalk #(get % "value" %) obj))
Run Code Online (Sandbox Code Playgroud)