Sponsored by AppSignal
Would you like to see your link here? Contact us
Notesclub

Maps

livebook/6_key_value_data/2_maps.livemd

Maps

import IEx.Helpers

History

last changes for Erlang before Elixir 1.0

i([{:one, 1}, {:two, 2}])
Term
  [one: 1, two: 2]
Data type
  List
Description
  This is what is referred to as a "keyword list". A keyword list is a list
  of two-element tuples where the first element of each tuple is an atom.
Reference modules
  Keyword, List
Implemented protocols
  Collectable, Enumerable, IEx.Info, Inspect, List.Chars, String.Chars

Ruby syntax for a map: {}

  • but in elixir {} is syntax for tuple
  • alrady first element in erlang
map = %{one: 1, two: 2}
%{one: 1, two: 2}
# list of two tuples
keyword = [one: 1, two: 2]
[one: 1, two: 2]
keyword.one
# yep
keyword[:one]
1

Syntax and Implementation

a = [1, 2, 3]
# nope, inefficient in elixir
a[2]

Syntactically, keywords are sometimes preferrable. For example, the last argument of a function. If it is a keyword, we can do this: fun(a, option_one:1, option_2: 2)

Maps have better performance!

map = %{"key1" => "value1", "key2" => "value2"}
%{"key1" => "value1", "key2" => "value2"}
life = %{{1, 1} => true, {1, 2} => false}
%{{1, 1} => true, {1, 2} => false}
person = %{name: "Jane", profession: "programmer"}
%{name: "Jane", profession: "programmer"}

Access

Map.get(person, :name)
"Jane"
{Map.get(person, :name), person.name, person[:name], Map.fetch(person, :name)}
{"Jane", "Jane", "Jane", {:ok, "Jane"}}

Updates

new_person = %{person | name: "John", profession: "Author"}
%{name: "John", profession: "Author"}
Map.put(person, :name, "John")
%{name: "John", profession: "programmer"}
person
|> Map.put(:name, "John")
|> Map.put(:profession, "author")
%{name: "John", profession: "author"}
updated_person =
  Map.update(person, :profession, "unknown", fn profession ->
    "senior " <> profession
  end)
%{name: "Jane", profession: "senior programmer"}
updated_person =
  Map.update(person, :professio, "unknown", fn profession ->
    "senior " <> profession
  end)
%{name: "Jane", professio: "unknown", profession: "programmer"}

Bulk

Map.keys(person)
[:name, :profession]
Map.values(person)
["Jane", "programmer"]
{Map.keys(person), Map.values(person)}
{[:name, :profession], ["Jane", "programmer"]}
IEx.Helpers.i(person)
Term
  %{name: "Jane", profession: "programmer"}
Data type
  Map
Reference modules
  Map
Implemented protocols
  Collectable, Enumerable, IEx.Info, Inspect
Map.to_list(person)
[name: "Jane", profession: "programmer"]
list = [{"name", "Jane"}, {"profession", "programmer"}]
[{"name", "Jane"}, {"profession", "programmer"}]
Enum.into(list, %{})
%{"name" => "Jane", "profession" => "programmer"}