Dealing with complicated nesting in API JSON requests in a functional way

Hello,

I have a question about dealing with complicated API requests in a functional way. If we are given a JSON

 {
   “room_id1”: {
      “date1”: {
        “id”: "3",
        “other_variables”: 1,
        “other_variables”: 2,
        “important_stuff”: {
          “id”: “2342”,
          “child_id1”: {
            “var1”: 1,
            “var2”: 1,
            “var3”: true,
          },
          “child_id2”: {
            “var1”: 2,
            “var2”: 2,
            “var3”: true,
          },…..	
  }
}

and we want to take information held in the keys, in the inner most object (i’ve called it important stuff). Such that the final data looks like this:

 [{
   room_id: “room_id1”,
   date: “date1”,
   child_id: “child_id1”,
   var1: 1,
   var2: 1,
   var3: true
},

 {
   room_id: “room_id2”,
   date: “date2”,
   child_id: “child_id2”,
   var1: 2,
   var2: 2,
   var3: true
}]

How might we manage this in a functional way, without side effects? At the moment, I have triple nested Enum.each looping over JSON response, building the object which is then inserted directly into the database. I would really like to separate the transforming of the API data with the inserting of that data in the database.

EDIT: I should mention that I did a search, and read this post (What's the best way to access and retrieve data from deeply nested Maps and Lists?) but I found that the solution was more specific to dealing with nested maps inside lists. I also had a look at the Kernal.get_in method that was mentioned (http://elixir-lang.org/docs/master/elixir/Kernel.html#get_in/2) and it seems that this will not be helpful if you don’t know what the keys will be (unique identifiers and dates are the keys). In my circumstance, the keys are valuable information, and we don’t know how many ‘children’ there are.

1 Like

Have solved this probelm with list comprehensions. EG:

for {room_id, room} <- data,
     {date, obj} <- room,
     is_map(obj),
     {child_id, child} <- obj["important_stuff"],,
     child_id != "id" do
       %{
        room_id: room_id,
        date: date,
        ...
      }
   end
3 Likes