2012-03-08 71 views
4

我正試圖清理Clojure中的一些JSON數據。 JSON文檔中的一些值封裝在具有關聯(且不再需要)元數據的對象中。我開始像一個JSON文件:Clojure:如何使用特定鍵摺疊嵌套地圖?

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

使用柴我解析此JSON,並得到如下數據結構:

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

我的目標是「崩潰」的嵌套地圖與「值」鍵,放下「foo」assoc,然後將值分配給高一級的地圖鍵(例如,「street」,「zip」,「name」)。由此產生的數據結構將如下所示:

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

這裏的任何幫助將是美好的,謝謝!

回答

8

聽起來像是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))