2012-03-08 3 views
4

Я пытаюсь очистить некоторые данные JSON в Clojure. Некоторые значения в документе 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" } 
     } 
    ] 
} } 

Использование Cheshire я разобрать этот 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"}} 
    ] 
} } 

Моя цель заключается в «коллапс» эти вложенные карты с «значение» key, отбросить «foo» -сообщество и присвоить значение ключу карты на один уровень выше (например, «улица», «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)) 
Смежные вопросы