Update nested maps in Elixir

Being a functional programming language, Elixir is a bit different from other languages when it comes to update a nested data structure.

For example, in javascript we could do:

data = {
  inner: {
    one: {
      a: 1
    },
    two: {
      b: 45
    }
  }
}

data.inner.one.a = 2

In Elixir you have to build a new map with the updated information, for example:

data = %{
  inner: %{
    one: %{
      a: 1
    },
    two: %{
      b: 45
    }
  }
}

new_one = %{data.inner.one | a: 2}
new_inner = %{data.inner | one: new_one}
new_data = %{data | inner: new_inner}

which is not very handy.

In other functional languages like Haskell, there are libraries like Lenses that aims to solve the problem. In Elixir the kernel have an put_in function that acts in a similar way:

data = put_in(data, [:inner, :one, :a], 2)

You can find other similar functions in the Kernel documentation