So I’m really loving elixir. BY FAR the most excruciating piece of learning a functional language for me is having to “transform” all my input data so that it includes ALL desired output data. In a mutable language like ruby you can have loops and iterators that just update variables (maps, counters, etc) outside the scope. This makes it super easy to wrangle complex data structures… but in Elixir it’s taking me quite awhile to deal with all this.
I wanted to make a little “database” in this thread that I can constantly come back to and reference of all the best ways you might do simple/medium/advanced data transformations. The advanced ones are too many to include in this thread but I feel like there are a lot of simple/medium ones that you can count on 2 hands that you use over and over and over.
I will keep adding to this thread but here are a few to start off…
A. Transform all values inside a map
input: %{a: "hello", b: "world"}
output: %{a: "HELLO", b: "WORLD"}
Answers:
x |> Enum.reduce(%{}, fn {k, v}, acc -> Map.put(acc, k, String.upcase(v)) end)
for({k, v} <- x, into: %{}, do: {k, String.upcase(v)})
:maps.map(fn (_k,v) -> String.upcase(v) end, i)
A2. Transform value inside a map for a specific key
input: %{a: "hello", b: "world"}
output: %{a: "hello", b: "WORLD"}
A3. Transform value for specific key inside a nested map
input: %{person: %{first: "Jose", last: "valim"}, age: 100}
input: %{person: %{first: "JOSE", last: "VALIM"}, age: 100}
Answers:
x |> update_in([:person, :last], &String.upcase(&1))
B. Transform all values inside a list of map
input: [%{a: "hello", b: "world"}, %{a: "fizz", b: "buzz}]
output: [%{a: "HELLO", b: "WORLD"}, %{a: "WORLD", b: "BUZZ}]
B2. Transform one value inside a list of map for a specific key
input: [%{a: "hello", b: "world"}, %{a: "fizz", b: "buzz}]
output: [%{a: "hello", b: "WORLD"}, %{a: "fizz", b: "BUZZ}]
Answers:
x |> Enum.map(fn m -> Map.update(m, :b, nil, &String.upcase(&1)) end)
C. Push to a list in a map
input: %{list: []}
output: %{list: [1]}
Answers:
x |> update_in([:list], &[1 | &1])
I will add more as I go, feel free to add your own