Clojure: How to collapse nested cards using a specific key?

I am trying to clear some JSON data in Clojure. Some values ​​in a JSON document are encapsulated in objects with associated (and no longer necessary) metadata. I start with a JSON document, for example:

{ "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" } } ] } } 

Using Cheshire I parse this JSON and get the following data structure:

 { "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"}} ] } } 

My goal is to "collapse" those nested cards with the "value" key, discard the "foo" message and assign the value to the card key one level higher (for example, "street", "zip", name "). The resulting data structure will look So:

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

Any help here would be great, thanks!

+4
source share
1 answer

Sounds like work for clojure.walk/postwalk !

 (defn collapse [obj] (postwalk (fn [obj] (or (and (map? obj) (get obj "value")) obj)) obj)) 

In fact, you can shorten this because get ready to work with objects other than a map (it just returns nil ), but I think it’s much more clear what happens in the first version.

 (defn collapse [obj] (postwalk #(get % "value" %) obj)) 
+8
source

Source: https://habr.com/ru/post/1400465/


All Articles