Recursion and Flat Map

Use of recursion and pattern matching in this module to create a flat map of a JSON object.

This example comes from a video presentation From Front End to Full Stack with Elixir & Phoenix that Lauren Tan presented. She is an awesome presenter. Highly recommend it.

In the presentation she has a slide where you can see the the use of recursion and pattern matching to flatten a JSON object (that got converted into a Map).

defmodule Json do

 def flatten(%{} =  json) when json == %{}, do: %{}
 def flatten(%{} = json) do
   json
   |> Map.to_list()
   |> to_flat_map(%{})
 end

 defp to_flat_map([{_k, %{} = v} | t], acc), do: to_flat_map(Map.to_list(v), to_flat_map(t, acc))
 defp to_flat_map([{k, v} | t], acc), do: to_flat_map(t, Map.put_new(acc, k, v))
 defp to_flat_map([], acc), do: acc

end

Flattening JSON

If you take the above module and apply it with the json below you can see what the end result is. It flattens it and then makes it easy to access with.


iex> example = %{
    id: 2,
    name: "Ervin Howell",
    username: "Antonette",
    email: "Shanna@melissa.tv",
    address: %{
      street: "Victor Plains",
      suite: "Suite 879",
      city: "Wisokyburgh",
      zipcode: "90566-7771",
      geo: %{
        lat: "-43.9509",
        lng: "-34.4618"
      }
    },
    phone: "010-692-6593 x09125",
    website: "anastasia.net",
    company: %{
      name: "Deckow-Crist",
      catchPhrase: "Proactive didactic contingency",
      bs: "synergize scalable supply-chains"
    }
  }


iex> Json.flatten(example)
%{
  bs: "synergize scalable supply-chains",
  catchPhrase: "Proactive didactic contingency",
  city: "Wisokyburgh",
  email: "Shanna@melissa.tv",
  id: 2,
  lat: "-43.9509",
  lng: "-34.4618",
  name: "Ervin Howell",
  phone: "010-692-6593 x09125",
  street: "Victor Plains",
  suite: "Suite 879",
  username: "Antonette",
  website: "anastasia.net",
  zipcode: "90566-7771"
}

Being able to flatten a nested JSON can easily speed up development on parsing JSON. Make it part of your tool belt.