9mm

9mm

Common data transform patterns - please add yours!

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

Most Liked

kokolegorille

kokolegorille

My small contrib for A :slight_smile:

iex> i = %{a: "hello", b: "world"}
iex> o = %{i | a: "HELLO", b: "WORLD"}

# or

iex> o = i |> Enum.reduce(%{}, fn {k, v}, acc -> Map.put(acc, k, String.upcase(v)) end)
peerreynders

peerreynders

input = %{list: []}
output = update_in(input, [:list], &[1 | &1])
IO.inspect(output)
iex(1)> input = %{list: []}
%{list: []}
iex(2)> output = update_in(input, [:list], &[1 | &1])
%{list: [1]}
iex(3)> IO.inspect(output)
%{list: [1]}
%{list: [1]}
iex(4)> 
peerreynders

peerreynders

input = %{person: %{first: "Jose", last: "valim"}, age: 100}
output = update_in(input, [:person, :last], &String.upcase(&1))
IO.inspect(output)
iex(1)> input = %{person: %{first: "Jose", last: "valim"}, age: 100}
%{age: 100, person: %{first: "Jose", last: "valim"}}
iex(2)> output = update_in(input, [:person, :last], &String.upcase(&1))
%{age: 100, person: %{first: "Jose", last: "VALIM"}}
iex(3)> IO.inspect(output)
%{age: 100, person: %{first: "Jose", last: "VALIM"}}
%{age: 100, person: %{first: "Jose", last: "VALIM"}}
iex(4)> 

Last Post!

peerreynders

peerreynders

With a name like that it wouldn’t :lol: and into %{} diverts attention from Map.new/1.

iex(1)> i = %{a: "hello", b: "world"}
%{a: "hello", b: "world"}
iex(2)> o = Map.new(i, fn ({k,v}) -> {k,String.upcase(v)} end)
%{a: "HELLO", b: "WORLD"}
iex(3)>

Where Next?

Popular in Guides/Tuts Top

benwilson512
Correct if me I’m wrong, as best I can tell there aren’t any reasons to use mix run --no-halt in production vs releases. The marginal val...
New
niku
I have published an elixir project with using Travis CI. I would like to share some tips &amp; thoughts that I was getting through this ...
New
hauleth
Some time ago someone suggested me to write article about how I have configured my Vim to work with Elixir, now there it is: https://med...
New
siever
I just wrote a simple guide on how you can setup a productive elixir development environment in vim. Its really easy, just a few steps. ...
New
lukertty
Install web-mode and mmm-mode first and put this in your config file: (require 'mmm-mode) (require 'web-mode) (setq mmm-global-mode 'may...
New
voltone
The EEF’s Security WG has released the first public draft of the Secure Coding and Deployment Hardening Guidelines for BEAM languages. “...
New
marcin
This post is intended to be a guide for others, I was running a remote debugger for the first time and appreciate feedback on how I could...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54092 488
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New