View Source WuunderUtils.Maps (Wuunder Utils v0.9.0)

Contains a set of helpers to deal with some complex stuff with Maps and Structs

Summary

Functions

Tests if the map or struct is present

Converts keys in maps to atoms. By default, this function will only atomize strings that already exist. Note: skips structs.

Removes a deeply nested set of keys

Acts as Kernel.get_in but can also be used on Structs. Has a lot of more extra functionalities

Creates a map from a given set of fields. The output will always be a string.

Acts as Kernel.put-in but can also be used on Structs. Has a lot of more extra functionalities

Removes a key from a map. Doesn't matter if the key is an atom or string

Deletes a list of keys from a map (and all nested maps, lists) Usefull when you want to scrub out IDs for instance.

Trims an incoming map/list/tuple. Removes all keys that have a nil value. Structs with an empty value will reset to the default value. Items in lists and tuples that contain nil values will be deleted.

Flattens a map. This results in a map that just contains one level

Creates a clean map from a given struct. This function deep structs, maps, lists etc. to a map and uses a set of default transformers as defined in default_struct_fransform/0.

Retrieves a key from a map regardless of the key type (atom/string) Note: This function does not generate new atoms on the fly.

Maps a given function over entire structure (map/list/struct/tuple)

Generates an empty map and list from a given set of keys

Tests if the given map only consists of atom keys

Acts as an IndifferentMap. Put a key/value regardless of the key type. If the map contains keys as atoms, the value will be stored as atom: value. If the map contains strings as keys it will store the value as binary: value

Only puts value in map when value is actually nil (not the same as empty)

Only puts value in map when the value is considered empty

Conditionally puts a value to a given map. Depending on the condition or the value, the key+value will be set to the map

Maps a given field from given (if not in map)

Mass maps a given input with aliasses

Converts keys in maps to strings. Note: skips structs. So you need to convert these to maps first.

Types

@type map_key() :: atom() | binary()

Functions

@spec any?(Ecto.Association.NotLoaded.t() | nil | map()) :: boolean()

Tests if the map or struct is present

Examples

iex> WuunderUtils.Maps.any?(nil)
false

iex> WuunderUtils.Maps.any?(%{})
false

iex> WuunderUtils.Maps.any?(%{a: 1})
true

iex> WuunderUtils.Maps.any?(%Person{})
true

iex> WuunderUtils.Maps.any?(%Ecto.Association.NotLoaded{})
false
Link to this function

atomize_keys(value, options \\ [existing_atoms: true])

View Source
@spec atomize_keys(any(), Keyword.t()) :: any()

Converts keys in maps to atoms. By default, this function will only atomize strings that already exist. Note: skips structs.

Examples

iex> WuunderUtils.Maps.atomize_keys(%{
...>   "first_name" => "Peter",
...>   "last_name" => "Griffin",
...>   "skills" => [%{"code" => "A", "title" => "Talking"}, %{"code" => "B", "title" => "Moving"}]
...> })
%{
  first_name: "Peter",
  last_name: "Griffin",
  skills: [%{code: "A", title: "Talking"}, %{code: "B", title: "Moving"}]
}

iex> WuunderUtils.Maps.atomize_keys(%Person{
...>   first_name: "Peter",
...>   last_name: "Pan",
...>   date_of_birth: ~D[1980-01-02],
...>   weight: Decimal.new("81.5"),
...>   country: %Country{code: "UK"},
...>   time_of_death: ~T[13:37:37],
...>   meta: %{"skills" => [%{"code" => "A", "title" => "Talking"}, %{"code" => "B", "title" => "Moving"}]}
...> })
%Person{
  first_name: "Peter",
  last_name: "Pan",
  date_of_birth: ~D[1980-01-02],
  weight: Decimal.new("81.5"),
  country: %Country{code: "UK"},
  time_of_death: ~T[13:37:37],
  meta: %{skills: [%{code: "A", title: "Talking"}, %{code: "B", title: "Moving"}]}
}
Link to this function

deep_delete(value, path)

View Source
@spec deep_delete(any(), [atom()] | String.t()) :: any()

Removes a deeply nested set of keys

Examples

iex> WuunderUtils.Maps.deep_delete(%{"data" => [%{"name" => "Piet"}, %{"name" => "Henk"}]}, "data.0.name")
%{"data" => [%{}, %{"name" => "Henk"}]}

iex> person = %Person{
...>   country: %Country{code: "NL"},
...>   address: %Address{
...>     street: "Teststreet",
...>     company: %Company{name: "Wuunder"}
...>   },
...>   meta: %{
...>     skills: [
...>       "programmer",
...>       "manager",
...>       %{type: "hobby", name: "painting", grades: {"A+", "C"}}
...>     ]
...>   }
...> }
...>
...> WuunderUtils.Maps.deep_delete(person, [:country, :code])
%Person{
  country: %Country{code: ""},
  address: %Address{
    street: "Teststreet",
    company: %Company{name: "Wuunder"}
  },
  meta: %{
    skills: [
      "programmer",
      "manager",
      %{type: "hobby", name: "painting", grades: {"A+", "C"}}
    ]
  }
}
iex> WuunderUtils.Maps.deep_delete(person, "meta.skills.1")
%Person{
  country: %Country{code: "NL"},
  address: %Address{
    street: "Teststreet",
    company: %Company{name: "Wuunder"}
  },
  meta: %{
    skills: [
      "programmer",
      %{type: "hobby", name: "painting", grades: {"A+", "C"}}
    ]
  }
}
Link to this function

deep_get(value, path, default \\ nil)

View Source

Acts as Kernel.get_in but can also be used on Structs. Has a lot of more extra functionalities:

  • You can access lists (nested too)
  • You can use mixed keys, they can be Atoms or Strings
  • You can use a list to access the properties or a string representation

Examples

iex> person = %Person{
...>   country: %Country{code: "NL"},
...>   address: %Address{
...>     street: "Teststreet",
...>     company: %Company{name: "Wuunder"}
...>   },
...>   meta: %{
...>     skills: [
...>       "programmer",
...>       "manager",
...>       %{type: "hobby", name: "painting", grades: {"A+", "C"}}
...>     ]
...>   }
...> }
...>
...> WuunderUtils.Maps.deep_get(person, [:country, :code])
"NL"
iex> WuunderUtils.Maps.deep_get(person, "country.code")
"NL"
iex> WuunderUtils.Maps.deep_get(person, [:address, :company])
%Company{name: "Wuunder"}
iex> WuunderUtils.Maps.deep_get(person, [:address, :company, :name])
"Wuunder"
iex> WuunderUtils.Maps.deep_get(person, [:meta, :skills])
["programmer", "manager", %{name: "painting", type: "hobby", grades: {"A+", "C"}}]
iex> WuunderUtils.Maps.deep_get(person, [:meta, :skills, 1])
"manager"
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.1")
"manager"
iex> WuunderUtils.Maps.deep_get(person, [:meta, :skills, 2, :type])
"hobby"
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.2.type")
"hobby"
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.2.non_existent")
nil
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.2.non_existent", "default")
"default"
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.2.grades.0")
"A+"
iex> WuunderUtils.Maps.deep_get(person, "meta.skills.2.grades.2", "none")
"none"

iex> keyword_list = [
...>   name: "Henk",
...>   last_name: "Jansen",
...>   addresses: [
...>     %{"street" => "Laan", "number" => 1},
...>     %{"street" => "Straat", "number" => 1337}
...>   ]
...> ]
...>
iex> WuunderUtils.Maps.deep_get(keyword_list, "name")
"Henk"
iex> WuunderUtils.Maps.deep_get(keyword_list, "addresses")
[%{"number" => 1, "street" => "Laan"}, %{"number" => 1337, "street" => "Straat"}]
iex> WuunderUtils.Maps.deep_get(keyword_list, "addresses.0")
%{"number" => 1, "street" => "Laan"}
iex> WuunderUtils.Maps.deep_get(keyword_list, "addresses.1.street")
"Straat"
iex> WuunderUtils.Maps.deep_get(keyword_list, "addresses.1.other_field", "none")
"none"
iex> WuunderUtils.Maps.deep_get(keyword_list, "addresses.2.other_field", "none")
nil
Link to this function

deep_get_values(value, fields)

View Source
@spec deep_get_values(map() | struct() | list(), list()) :: map()

Creates a map from a given set of fields. The output will always be a string.

Examples

iex> person = %Person{
...>   country: %Country{code: "NL"},
...>   address: %Address{
...>     street: "Teststreet",
...>     company: %Company{name: "Wuunder"}
...>   },
...>   meta: %{
...>     skills: [
...>       "programmer",
...>       "manager",
...>       %{type: "hobby", name: "painting"}
...>     ]
...>   }
...> }
...>
...> WuunderUtils.Maps.deep_get_values(
...>   person,
...>   [
...>     [:country, :code],
...>     [:address, :street],
...>     [:meta, :skills, 2, :type]
...>   ]
...> )
%{
  "address" => %{"street" => "Teststreet"},
  "country" => %{"code" => "NL"},
  "meta" => %{
    "skills" => [
      %{"type" => "hobby"}
    ]
  }
}
Link to this function

deep_put(value, path, value_to_set)

View Source
@spec deep_put(
  map() | struct() | list() | nil,
  [atom() | String.t()] | String.t(),
  any()
) :: any()

Acts as Kernel.put-in but can also be used on Structs. Has a lot of more extra functionalities:

  • You can access lists (nested too)
  • You can use mixed keys, they can be Atoms or Strings
  • You can use a list to access the properties or a string representation

Examples

iex> person = %Person{
...>   country: %Country{code: "NL"},
...>   address: %Address{
...>     street: "Teststreet",
...>     company: %Company{name: "Wuunder"}
...>   },
...>   meta: %{
...>     skills: [
...>       "programmer",
...>       "manager",
...>       %{type: "hobby", name: "painting"}
...>     ]
...>   }
...> }
iex> WuunderUtils.Maps.deep_put(person, [:first_name], "Piet")
%Person{person | first_name: "Piet"}
iex> WuunderUtils.Maps.deep_put(person, [:country, :code], "US")
%Person{person | country: %Country{code: "US"}}
iex> WuunderUtils.Maps.deep_put(person, [:meta, :skills, 1], "vaultdweller")
%Person{person | meta: %{skills: ["programmer", "vaultdweller", %{name: "painting", type: "hobby"}]}}
iex> WuunderUtils.Maps.deep_put(person, [:meta, :skills, 2, :name], "walking")
%Person{person | meta: %{skills: ["programmer", "manager", %{name: "walking", type: "hobby"}]}}
iex> WuunderUtils.Maps.deep_put(person, "meta.skills.2.name", "walking")
%Person{person | meta: %{skills: ["programmer", "manager", %{name: "walking", type: "hobby"}]}}
@spec delete(any(), map_key() | non_neg_integer()) :: any()

Removes a key from a map. Doesn't matter if the key is an atom or string

Examples

iex> WuunderUtils.Maps.delete(%{length: 255, weight: 100}, :length)
%{weight: 100}

iex> WuunderUtils.Maps.delete(%{length: 255, weight: 100}, "length")
%{weight: 100}

iex> WuunderUtils.Maps.delete(%{"value" => 50, "currency" => "EUR"}, "currency")
%{"value" => 50}

iex> WuunderUtils.Maps.delete(%{"value" => 50, "currency" => "EUR"}, :currency)
%{"value" => 50}

iex> WuunderUtils.Maps.delete(["a", "b", "c"], 1)
["a", "c"]

iex> WuunderUtils.Maps.delete({"a", "b", "c"}, 1)
{"a", "c"}

iex> country = %Country{code: "NL"}
...>
...> WuunderUtils.Maps.delete(country, :code)
%Country{code: ""}

iex> country = %Country{code: "NL"}
...>
...> WuunderUtils.Maps.delete(country, "code")
%Country{code: ""}

iex> country = %Country{code: "NL"}
...>
...> WuunderUtils.Maps.delete(country, "does_not_exist")
%Country{code: "NL"}
Link to this function

delete_all(map, keys_to_delete)

View Source
@spec delete_all(map(), [String.t() | atom()]) :: map()

Deletes a list of keys from a map (and all nested maps, lists) Usefull when you want to scrub out IDs for instance.

Examples

iex> WuunderUtils.Maps.delete_all(
...>   %{
...>      shipment: %{
...>        id: "shipment-id",
...>        wuunder_id: "WUUNDERID"
...>      },
...>      order_lines: [
...>        %{id: "123", sku: "SKU01"},
...>        %{id: "456", sku: "SKU02"},
...>        %{id: "789", sku: "SKU03"}
...>      ],
...>      meta: %{
...>        configuration_id: "nothing"
...>      }
...>   },
...>   [:id, :configuration_id]
...> )
%{
  meta: %{},
  order_lines: [%{sku: "SKU01"}, %{sku: "SKU02"}, %{sku: "SKU03"}],
  shipment: %{wuunder_id: "WUUNDERID"}
}

iex> WuunderUtils.Maps.delete_all([
...>   %{id: "123", name: "test1"},
...>   %{id: "456", name: "test2"},
...>   %{id: "789", name: "test3"}
...> ], [:id])
[%{name: "test1"}, %{name: "test2"}, %{name: "test3"}]
@spec delete_empty(any()) :: any()

Trims an incoming map/list/tuple. Removes all keys that have a nil value. Structs with an empty value will reset to the default value. Items in lists and tuples that contain nil values will be deleted.

Examples

  iex> WuunderUtils.Maps.delete_empty(%{name: nil, last_name: "Jansen"})
  %{last_name: "Jansen"}

  iex> WuunderUtils.Maps.delete_empty(%{name: nil, last_name: nil})
  nil

  iex> WuunderUtils.Maps.delete_empty({1, 2, nil, 3, 4})
  {1, 2, 3, 4}

  iex> WuunderUtils.Maps.delete_empty([1, 2, nil, 3, 4])
  [1, 2, 3, 4]

  iex> WuunderUtils.Maps.delete_empty(%{items: [%{a: nil, b: nil}, %{a: 1, b: 2}]})
  %{items: [%{a: 1, b: 2}]}

  iex> WuunderUtils.Maps.delete_empty(%{items: [%{a: [1, nil, %{x: 1337, y: {1, nil, 2, {nil, nil}}}], b: nil}, %{a: 1, b: 2}]})
  %{items: [%{a: [1, %{y: {1, 2}, x: 1337}]}, %{a: 1, b: 2}]}
Link to this function

flatten(map_list_or_tuple)

View Source
@spec flatten(map() | list() | tuple()) :: map()

Flattens a map. This results in a map that just contains one level

Options

  • key_separator (default .)
  • underscore_key (default true)
  • list_index_start (default 1)

Example

iex> WuunderUtils.Maps.flatten(%{
...>   test: "123",
...>   order_lines: [
...>     %{sku: "123", description: "test"},
...>     %{sku: "456", description: "test 2"}
...>   ],
...>   meta: %{
...>     data: "test"
...>   }
...> })
%{
  "test" => "123",
  "order_lines.1.sku" => "123",
  "order_lines.1.description" => "test",
  "order_lines.2.sku" => "456",
  "order_lines.2.description" => "test 2",
  "meta.data" => "test"
}

iex> WuunderUtils.Maps.flatten({1, 2, 3})
%{
  "1" => 1,
  "2" => 2,
  "3" => 3,
}

iex> WuunderUtils.Maps.flatten([
...>     %{sku: "123", description: "test"},
...>     %{sku: "456", description: "test 2"}
...> ])
%{
  "1.sku" => "123",
  "1.description" => "test",
  "2.sku" => "456",
  "2.description" => "test 2"
}

iex> WuunderUtils.Maps.flatten(
...>   %{
...>     test: "123",
...>     order_lines: [
...>       %{sku: "123", description: "test"},
...>       %{sku: "456", description: "test 2"}
...>     ],
...>     meta: %{
...>       data: "test"
...>     },
...>     tuple: {1, 2, 3}
...>   },
...>   key_separator: "_",
...>   list_index_start: 0
...> )
%{
  "test" => "123",
  "order_lines_0_sku" => "123",
  "order_lines_0_description" => "test",
  "order_lines_1_sku" => "456",
  "order_lines_1_description" => "test 2",
  "tuple_0" => 1,
  "tuple_1" => 2,
  "tuple_2" => 3,
  "meta_data" => "test"
}
@spec flatten(map() | list() | tuple(), Keyword.t()) :: map()
Link to this function

flatten(tuple, initial_map, key_prefix, options)

View Source
@spec flatten(map() | list() | tuple(), map(), String.t(), Keyword.t()) :: map()
@spec from_struct(any()) :: any()

Creates a clean map from a given struct. This function deep structs, maps, lists etc. to a map and uses a set of default transformers as defined in default_struct_fransform/0.

There is also an option to omit the transform option to add an extra set of transformers.

Took some inspiration from this great lib: https://github.com/prodis/miss-elixir/blob/0.1.5/lib/miss/map.ex

Note: It's also able to convert Ecto models to flat maps. It uses the defined Ecto fields for that.

Examples

iex> WuunderUtils.Maps.from_struct(%Person{
...>   first_name: "Peter",
...>   last_name: "Pan",
...>   date_of_birth: ~D[1980-01-02],
...>   weight: Decimal.new("81.5"),
...>   country: %{code: "UK"},
...>   time_of_death: ~T[13:37:37]
...> })
%{
  address: nil,
  date_of_birth: "1980-01-02",
  first_name: "Peter",
  last_name: "Pan",
  time_of_death: "13:37:37",
  weight: "81.5",
  country: %{code: "UK"},
  meta: %{}
}

iex> WuunderUtils.Maps.from_struct(
...>   %Person{
...>     first_name: "Peter",
...>     last_name: "Pan",
...>     date_of_birth: ~D[1980-01-02],
...>     weight: Decimal.new("81.5"),
...>     country: %Country{code: "UK"},
...>     time_of_death: ~T[13:37:37]
...>   },
...>   transform: [{Country, fn x -> "COUNTRY:" <> x.code end}]
...> )
%{
  address: nil,
  date_of_birth: "1980-01-02",
  first_name: "Peter",
  last_name: "Pan",
  time_of_death: "13:37:37",
  weight: "81.5",
  country: "COUNTRY:UK",
  meta: %{}
}

iex> WuunderUtils.Maps.from_struct(
...>   %Person{
...>     address: %Address{
...>       street: "Straat",
...>       number: 13,
...>       zipcode: "1122AB"
...>     },
...>     first_name: "Peter",
...>     last_name: "Pan",
...>     date_of_birth: ~D[1980-01-02],
...>     weight: Decimal.new("81.5"),
...>     country: %{code: "UK"},
...>     time_of_death: ~T[13:37:37]
...>   }
...> )
%{
  address: %{company: nil, number: 13, street: "Straat", zipcode: "1122AB"},
  date_of_birth: "1980-01-02",
  first_name: "Peter",
  last_name: "Pan",
  time_of_death: "13:37:37",
  weight: "81.5",
  country: %{code: "UK"},
  meta: %{}
}
Link to this function

from_struct(value, transform)

View Source
@spec from_struct(any(), list()) :: any()
Link to this function

get(map, key, default \\ nil)

View Source
@spec get(any(), map_key() | non_neg_integer(), any()) :: any()

Retrieves a key from a map regardless of the key type (atom/string) Note: This function does not generate new atoms on the fly.

Examples

iex> WuunderUtils.Maps.get(%{value: 20}, :value)
20

iex> WuunderUtils.Maps.get(%{"value" => 20}, :value)
20

iex> WuunderUtils.Maps.get(%{value: 20}, "value")
20

iex> WuunderUtils.Maps.get(%{value: 20}, "non-existent")
nil

iex> WuunderUtils.Maps.get(%{value: 20}, :weight)
nil

iex> WuunderUtils.Maps.get(%{value: 20}, :weight, 350)
350

iex> WuunderUtils.Maps.get(%{value: 20}, "currency", "EUR")
"EUR"

iex> WuunderUtils.Maps.get([name: "Henk", name: "Kees", last_name: "Jansen"], "name")
"Henk"

iex> WuunderUtils.Maps.get(["a", "b", "c"], 1)
"b"


iex> WuunderUtils.Maps.get(["a", "b", "c"], 3, "d")
"d"

iex> WuunderUtils.Maps.get({"a", "b", "c"}, 1)
"b"

iex> WuunderUtils.Maps.get({"a", "b", "c"}, 3, "d")
"d"
Link to this macro

is_valid_map_atom_key(key)

View Source (macro)
Link to this macro

is_valid_map_binary_key(key)

View Source (macro)
Link to this macro

is_valid_map_key(key)

View Source (macro)
@spec map(any(), function()) :: any()

Maps a given function over entire structure (map/list/struct/tuple)

Examples

  iex> WuunderUtils.Maps.map(%{name: " test ", data: ["some item", "other item   ", %{x: "  value"}]}, &WuunderUtils.Presence.trim/1)
  %{data: ["some item", "other item", %{x: "value"}], name: "test"}
@spec new(String.t() | list()) :: map()

Generates an empty map and list from a given set of keys

Examples

iex> WuunderUtils.Maps.new([:person, :name, :meta, 0, :hobby, :type])
%{"person" => %{"name" => %{"meta" => [%{"hobby" => %{"type" => %{}}}]}}}

iex> WuunderUtils.Maps.new([:person, :name, :meta, 0, :hobbies, 0, :type])
%{"person" => %{"name" => %{"meta" => [%{"hobbies" => [%{"type" => %{}}]}]}}}
@spec new(map() | list(), list()) :: map() | list()
@spec only_atom_keys?(map() | struct()) :: boolean()

Tests if the given map only consists of atom keys

Examples

iex> WuunderUtils.Maps.only_atom_keys?(%{a: 1, b: 2})
true

iex> WuunderUtils.Maps.only_atom_keys?(%{:a => 1, "b" => 2})
false

iex> WuunderUtils.Maps.only_atom_keys?(%{"a" => 1, "b" => 2})
false
@spec put(map() | struct() | list() | nil, String.t() | atom(), any()) ::
  map() | struct() | list()

Acts as an IndifferentMap. Put a key/value regardless of the key type. If the map contains keys as atoms, the value will be stored as atom: value. If the map contains strings as keys it will store the value as binary: value

Examples

iex> WuunderUtils.Maps.put(%{value: 20}, :weight, 350)
%{value: 20, weight: 350}

iex> WuunderUtils.Maps.put(["a", "b", "c"], 1, "d")
["a", "d", "c"]

iex> WuunderUtils.Maps.put(["a", "b", "c"], 4, "d")
["a", "b", "c"]

iex> WuunderUtils.Maps.put(%{value: 20, weight: 200}, "weight", 350)
%{value: 20, weight: 350}

iex> WuunderUtils.Maps.put(%{value: 20}, "weight", 350)
%{:value => 20, "weight" => 350}

iex> WuunderUtils.Maps.put(%{"weight" => 350}, :value, 25)
%{"weight" => 350, "value" => 25}

iex> WuunderUtils.Maps.put(%{"weight" => 350}, "value", 25)
%{"weight" => 350, "value" => 25}
Link to this function

put_if_not_nil(map, key, value)

View Source
@spec put_if_not_nil(map(), map_key(), any()) :: map()

Only puts value in map when value is actually nil (not the same as empty)

Examples

iex> WuunderUtils.Maps.put_if_not_nil(%{street: "Straat"}, :street, "Laan")
%{street: "Laan"}

iex> WuunderUtils.Maps.put_if_not_nil(%{street: "Straat"}, :street, nil)
%{street: "Straat"}

iex> WuunderUtils.Maps.put_if_not_nil(%{street: "Straat"}, :street, "     ")
%{street: "     "}
Link to this function

put_if_present(map, key, value)

View Source
@spec put_if_present(map(), map_key(), any()) :: map()

Only puts value in map when the value is considered empty

Examples

iex> WuunderUtils.Maps.put_if_present(%{street: "Straat"}, :street, "Laan")
%{street: "Laan"}

iex> WuunderUtils.Maps.put_if_present(%{street: "Straat"}, :street, nil)
%{street: "Straat"}

iex> WuunderUtils.Maps.put_if_present(%{street: "Straat"}, :street, "     ")
%{street: "Straat"}
Link to this function

put_when(map, condition, key, value)

View Source
@spec put_when(map(), function() | boolean(), map_key(), any()) :: map()

Conditionally puts a value to a given map. Depending on the condition or the value, the key+value will be set to the map

Examples

iex> WuunderUtils.Maps.put_when(%{street: "Straat"}, 1 == 1, :number, 13)
%{number: 13, street: "Straat"}

iex> WuunderUtils.Maps.put_when(%{street: "Straat"}, fn -> "value" == "value" end, :number, 13)
%{number: 13, street: "Straat"}

iex> WuunderUtils.Maps.put_when(%{street: "Straat"}, 10 > 20, :number, 13)
%{street: "Straat"}
Link to this function

rename_key(map, from, to)

View Source
@spec rename_key(map(), atom(), atom()) :: map()

Maps a given field from given (if not in map)

Examples

iex> WuunderUtils.Maps.rename_key(%{country: "NL"}, :country, :country_code)
%{country_code: "NL"}

iex> WuunderUtils.Maps.rename_key(%{"country" => "NL"}, :country, :country_code)
%{"country_code" => "NL"}

iex> WuunderUtils.Maps.rename_key(%{street_name: "Straatnaam"}, :street, :street_address)
%{street_name: "Straatnaam"}
Link to this function

rename_keys(map, aliasses)

View Source
@spec rename_keys(map(), map()) :: map()

Mass maps a given input with aliasses

Examples

iex> WuunderUtils.Maps.rename_keys(%{country: "NL", street: "Straat", number: 666}, %{country: :country_code, street: :street_name, number: :house_number})
%{country_code: "NL", house_number: 666, street_name: "Straat"}
@spec stringify_keys(any()) :: any()

Converts keys in maps to strings. Note: skips structs. So you need to convert these to maps first.

Examples

iex> WuunderUtils.Maps.stringify_keys(%{
...>   first_name: "Peter",
...>   last_name: "Griffin",
...>   skills: [%{code: "A", title: "Talking"}, %{code: "B", title: "Moving"}]
...> })
%{
  "first_name" => "Peter",
  "last_name" => "Griffin",
  "skills" => [%{"code" => "A", "title" => "Talking"}, %{"code" => "B", "title" => "Moving"}]
}

iex> WuunderUtils.Maps.stringify_keys(%Person{
...>   first_name: "Peter",
...>   last_name: "Pan",
...>   date_of_birth: ~D[1980-01-02],
...>   weight: Decimal.new("81.5"),
...>   country: %Country{code: "UK"},
...>   time_of_death: ~T[13:37:37],
...>   meta: %{skills: [%{code: "A", title: "Talking"}, %{code: "B", title: "Moving"}]}
...> })
%Person{
  first_name: "Peter",
  last_name: "Pan",
  date_of_birth: ~D[1980-01-02],
  weight: Decimal.new("81.5"),
  country: %Country{code: "UK"},
  time_of_death: ~T[13:37:37],
  meta: %{"skills" => [%{"code" => "A", "title" => "Talking"}, %{"code" => "B", "title" => "Moving"}]}
}