Joey Yi Zhao
Joey Yi Zhao

Reputation: 42644

What is the functional way to swap two values in a Map in elixir?

I have a map defined as below:

iex(tbc@192-168-1-8)2> map = %{ 1 => {name => "Joey"}, 2 => {name => "Lee"}}

I want to swap the value of the two name to make it looks like:

%{1 => %{"name" => "Lee"}, 2 => %{"name" => "Joey"}}

I know I can use below code to implement this:

iex(tbc@192-168-1-8)3> name1 = Map.get(map, 1)
%{"name" => "Joey"}
iex(tbc@192-168-1-8)4> name2 = Map.get(map, 2)
%{"name" => "Lee"}
iex(tbc@192-168-1-8)5> map = Map.put(map, 1, name2)
%{1 => %{"name" => "Lee"}, 2 => %{"name" => "Lee"}}
iex(tbc@192-168-1-8)6> map = Map.put(map, 2, name1)
%{1 => %{"name" => "Lee"}, 2 => %{"name" => "Joey"}}

but I don't think this is elixir style of coding. What is the functional way to implement this logic in elixir?

Upvotes: 1

Views: 333

Answers (2)

Adam Millerchip
Adam Millerchip

Reputation: 23147

You can define a new map by accessing the values of the old one:

%{1 => map[2], 2 => map[1]}

If you want to swap two elements while preserving the rest of the map, you can use

%{ map | 1 => map[2], 2 => map[1] }

In iex:

iex(1)> map = %{1 => "one", 2 => "two", 3 => "three", 4 => "four"}
%{1 => "one", 2 => "two", 3 => "three", 4 => "four"}
iex(2)> %{ map | 1 => map[2], 2 => map[1] }
%{1 => "two", 2 => "one", 3 => "three", 4 => "four"}

Upvotes: 1

Máté
Máté

Reputation: 2345

You can go about with using the with block, extracting the names first, and then creating a new map with them:

with name1 <- Map.get(map, 1),
     name2 <- Map.get(map, 2)
do
     %{1 => name2, 2 => name1}
end

Or you can do a simple function, pattern match on the keys, get the values and produce a new map:

def swap(%{1 => name1, 2 => name2} do
     %{1 => name2, 2 => name1}
end

The end result is the same in both occasions, it's up to your own preference on which you'd use.

Upvotes: 5

Related Questions