2012-03-08 10 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をドロップし、マップキーの値を1つ上のレベルに割り当てます(例: "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))