Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Maps

livebook-sessions/key-value-data.livemd

Maps

import IEx.Helpers

History

last changes for erlang before Elixir 1.0

i [{:one, 1}, {:two, 2}]

Ruby syntax for map {}

map = %{one: 1, two: 2}

Syntax and Implementation

keyword = [one: 1, two: 2]

# keyword.one # not allowed
keyword[:one]
a = [1, 2, 3]
a[2] # not possible

Syntactically, keywords are sometimes preferable. for example, the last argument of a function, if it is a keyword, we can do this: fun(a, option_one: 1, option_two: 2)

Maps have better performance than keyword

map = %{"key1" => 1, "key2" => 2}
life = %{{1, 1} => :live, {1, 2} => :dead}
person = %{name: "Jane", profession: "programmer"}

Access

{ Map.get(person, :name), person.name, person[:name], Map.fetch!(person, :name)}

Updates

new_person = %{ person| name: "John", profession: "Author" } # map update syntax
# it will throw an error if key is misspelled or not present in the map
person 
|> Map.put(:name, "Johnny")
|> Map.put(:profession, "author")

Bulk

{Map.keys(person), Map.values(person)}
Map.to_list(person)
list = [{"name", "Jane"}, {"profession", "programmer"}]
Map.new(list)
Enum.into(list, %{})
Enum.into(list, %{"age" => 21})

Defining Structs

We can make a struct in two ways

  1. using Keyword list 2.
defmodule User do
  defstruct [name: "Jill", age: 25]
  
  def new() do
    %User{name: "Bruce", age: 21}
  end
end
defmodule Point do
  defstruct [:x, :y]
end
User.new()
# %User{aeg: 27}
user = %User{age: 26}
Point.__struct__

The struct key and function

The only difference between struct and map is that the struct has __struct__ key

IEx.Helpers.exports(User)
# exports(User)
User.__struct__(%{age: 30})
User.__struct__(age: 31)
Map.keys(user)
user.__struct__

Protocols

IEx.Helpers.i %{}
IEx.Helpers.i %Point{}
is_map(%Point{})
is_struct(%Point{})
Enum.count(%{one: 1})
Enum.count(Point.__struct__)
user_struct = User.new()
user_struct.name
user_struct[:age]

Common structs in Elixir

IEx.Helpers.i Date.utc_today()
Date.utc_today() |> Map.keys()
DateTime.utc_now() |> Map.keys()