Iteraptor (iteraptor v1.15.0)
View SourceIteraptor makes complicated nested structures (currently Maps, Lists
  and Keywords) iteration easier.
Usage
Iterating, Mapping, Reducing
- Iteraptor.each/3to iterate a deeply nested map/list/keyword;
- Iteraptor.map/3to map a deeply nested map/list/keyword;
- Iteraptor.reduce/4to reduce a deeply nested map/list/keyword;
- Iteraptor.map_reduce/4to map and reduce a deeply nested map/list/keyword;
Flattening
- Iteraptor.to_flatmap/2to flatten a deeply nested map/list/keyword into flatten map with concatenated keys;
- Iteraptor.from_flatmap/3to “unveil”/“unflatten” the previously flattened map into nested structure;
Filtering
- Iteraptor.filter/3to filter the structure according to the value returned from each iteration (- trueto leave the element,- falseto discard.)
Summary
Types
The function that might be passed to all the traversion functions.
Functions
Iterates the given nested structure, calling the callback provided on each value. The key returned is an array of all the parent keys (and/or indices in a case of an array.)
Filters the deeply nested term, optionally calling the function on filtered entries.
Build a nested structure out of a flatmap given, decomposing the names of keys and handling lists carefully.
Produces a term ready-to-use with JSON interchange. Stringifies all keys and converts keywords to maps.
Maps the given nested structure, calling the callback provided on each value. The key returned is a concatenated names of all the parent keys (and/or indices in a case of an array.)
Iteration with mapping and reducing. The function of arity 2, called back on each
  iteration with {k, v} pair and an accumulator is accepted.
Iteration with reducing. The function of arity 2, called back on each
  iteration with {k, v} pair and an accumulator is accepted.
Build a flatmap out of nested structure, concatenating the names of keys.
Types
@type option() ::
  {:keys, :reverse}
  | {:yield, :all | :none | :maps | :lists}
  | {:structs, :values | :keep}
      @type options() :: [option()]
The function that might be passed to all the traversion functions.
When it’s a function or arity 1, it receives {key, value} tuple when the key
  is the list of keys down the nesting levels.
When its arity is 2, it receives key and value as separated arguments.
Functions
@spec each(Access.t(), traverse_fun(), options()) :: Access.t()
Iterates the given nested structure, calling the callback provided on each value. The key returned is an array of all the parent keys (and/or indices in a case of an array.)
The return value is self.
Parameters
- input: nested map/list/keyword to be walked through.
- fun: callback to be called on each- {key, value}pair, where- keyis an array or deeply nested keys; e.g. on- %{a: {b: 42}}will be called once, with tuple- {[:a, :b], 42};
- opts: the options to be passed to the iteration- yield:- [:all | :none | :maps | :lists]what to yield; default:- :allfor yielding values only
- keys:- [:reverse]reverse keys list to ease pattern matching; default:- nil
- structs:- [:values | :keep]how to handle structs; default:- :valuesfor treating them as- maps. When- :values, the nested structs are considered leaves and returned to the iterator instead of being iterated through; when- :keepit returns a struct back after iteration
 
Examples
iex> %{a: %{b: %{c: 42}}} |> Iteraptor.each(&IO.inspect/1)
{[:a, :b, :c], 42}
%{a: %{b: %{c: 42}}}
iex> %{a: %{b: %{c: 42}}} |> Iteraptor.each(&IO.inspect/1, yield: :all)
{[:a], %{b: %{c: 42}}}
{[:a, :b], %{c: 42}}
{[:a, :b, :c], 42}
%{a: %{b: %{c: 42}}}@spec filter(Access.t(), traverse_fun(), options()) :: Access.t()
Filters the deeply nested term, optionally calling the function on filtered entries.
The return value is the filtered term.
Parameters
- input: nested map/list/keyword to be filtered.
- fun: callback to be called on each- {key, value}to filter entries.
- opts: the options to be passed to the iteration (see- Iteraptpr.each/3)
Examples
iex> %{a: %{b: 42, e: %{f: 3.14, c: 42}, d: %{c: 42}}, c: 42, d: 3.14}
...> |> Iteraptor.filter(fn {key, _} -> :c in key end, yield: :none)
%{a: %{e: %{c: 42}, d: %{c: 42}}, c: 42}@spec from_flatmap(%{}, traverse_fun(), options()) :: Access.t()
Build a nested structure out of a flatmap given, decomposing the names of keys and handling lists carefully.
%{"a.b.c": 42, "a.b.d.0": nil, "a.b.d.1": 42, "a.e.0": :f, "a.e.1": 42}
|> Iteraptor.from_flatmap
#⇒ %{a: %{b: %{c: 42, d: [nil, 42]}, e: [:f, 42]}}Parameters
- input: flat map to be “expanded” to nested maps/lists,
- transformer: the transformer function to be called on all the elements,
- opts: additional options to be passed through.
Examples
iex> %{"a.b.c": 42} |> Iteraptor.from_flatmap
%{a: %{b: %{c: 42}}}
iex> %{"a.b.c": 42, "a.b.d": 42} |> Iteraptor.from_flatmap
%{a: %{b: %{c: 42, d: 42}}}
iex> %{"a.b.c": 42, "a.b.d": 42, "a.e": 42} |> Iteraptor.from_flatmap
%{a: %{b: %{c: 42, d: 42}, e: 42}}
iex> %{"0": 42, "1": 42} |> Iteraptor.from_flatmap
[42, 42]
iex> %{"1": :a1, "0": :a0, "2": :a2, "3": :a3, "4": :a4, "5": :a5,
...>   "6": :a6, "7": :a7, "8": :a8, "9": :a9, "10": :a10, "11": :a11}
...> |> Iteraptor.from_flatmap
[:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :a10, :a11]
iex> %{"0.a": 42, "0.b": 42} |> Iteraptor.from_flatmap
[%{a: 42, b: 42}]
iex> %{"a.0.0" => :b, "a.1" => 42, d: 42} |> Iteraptor.from_flatmap
%{a: [[:b], 42], d: 42}
iex> %{"a.b.c": 42, "a.b.d.0": nil, "a.b.d.1": 42, "a.e.0": :f, "a.e.1": 42}
...> |> Iteraptor.from_flatmap
%{a: %{b: %{c: 42, d: [nil, 42]}, e: [:f, 42]}}
iex> %{"0.a": 42, "0.b": 42} |> Iteraptor.from_flatmap(&IO.inspect/1)
{[0, :a], 42}
{[0, :b], 42}
[%{a: 42, b: 42}]@spec jsonify( Access.container() | any(), keyword() ) :: map()
Produces a term ready-to-use with JSON interchange. Stringifies all keys and converts keywords to maps.
If the option keys: false is given, leaves keys intact.
Examples
iex> Iteraptor.jsonify([foo: [:zzz], bar: :baz], values: true)
%{"foo" => ["zzz"], "bar" => "baz"}
iex> Iteraptor.jsonify(%{foo: [1, [bar: 2], 3], bar: [baz: 42]})
%{"foo" => [1, %{"bar" => 2}, 3], "bar" => %{"baz" => 42}}
iex> Iteraptor.jsonify([foo: [bar: [baz: :zoo], boo: 42]], values: true)
%{"foo" => %{"bar" => %{"baz" => "zoo"}, "boo" => 42}}
iex> Iteraptor.jsonify([foo: [bar: [baz: :zoo], boo: 42]], keys: false)
%{foo: %{bar: %{baz: :zoo}, boo: 42}}@spec map(Access.t(), traverse_fun(), options()) :: Access.t()
Maps the given nested structure, calling the callback provided on each value. The key returned is a concatenated names of all the parent keys (and/or indices in a case of an array.)
The return value is the result of subsequent calls to the transformer given.
Parameters
- input: nested map/list/keyword to be mapped.
- fun: callback to be called on each- {key, value}pair, where- keyis an array or deeply nested keys; e.g. on- %{a: {b: 42}}will be called once, with tuple- {[:a, :b], 42};
- opts: the options to be passed to the iteration (see- Iteraptpr.each/3)
Examples
iex> %{a: %{b: %{c: 42}}} |> Iteraptor.map(fn {_, v} -> v * 2 end)
%{a: %{b: %{c: 84}}}
iex> %{a: %{b: %{c: 42}}} |> Iteraptor.map(fn {k, _} -> Enum.join(k) end)
%{a: %{b: %{c: "abc"}}}
iex> %{a: %{b: %{c: 42}}}
...> |> Iteraptor.map(fn
...>      {[_], _} = self -> self
...>      {[_, _], _} -> "YAY"
...>    end, yield: :all)
%{a: %{b: "YAY"}}Iteration with mapping and reducing. The function of arity 2, called back on each
  iteration with {k, v} pair and an accumulator is accepted.
The return value is the tuple, consisting of mapped input and the accumulator from the last call to the passed map-reducer.
Parameters
- input: nested map/list/keyword to be mapped.
- fun: callback to be called on each- {key, value}, accpair, where- keyis an array or deeply nested keys,- valueis the value and- accis the accumulator;
- opts: the options to be passed to the iteration (see- Iteraptpr.each/3)
Examples
iex> %{a: %{b: %{c: 42}}}
...> |> Iteraptor.map_reduce([], fn
...>      {k, %{} = v}, acc -> {{k, v}, [Enum.join(k, ".") | acc]}
...>      {k, v}, acc -> {{k, v * 2}, [Enum.join(k, ".") <> "=" | acc]}
...>    end, yield: :all)
{%{a: %{b: %{c: 84}}}, ["a.b.c=", "a.b", "a"]}@spec reduce(Access.t(), Access.t(), traverse_fun(), options()) :: Access.t()
Iteration with reducing. The function of arity 2, called back on each
  iteration with {k, v} pair and an accumulator is accepted.
The return value is the result of the last call to the passed reducer function.
Parameters
- input: nested map/list/keyword to be mapped.
- fun: callback to be called on each- {key, value}, accpair, where- keyis an array or deeply nested keys,- valueis the value and- accis the accumulator;
- opts: the options to be passed to the iteration (see- Iteraptpr.each/3)
Examples
iex> %{a: %{b: %{c: 42}}}
...> |> Iteraptor.reduce([], fn {k, _}, acc ->
...>      [Enum.join(k, "_") | acc]
...>    end, yield: :all)
...> |> :lists.reverse()
["a", "a_b", "a_b_c"]Build a flatmap out of nested structure, concatenating the names of keys.
%{a: %{b: %{c: 42, d: [nil, 42]}, e: [:f, 42]}} |> Iteraptor.to_flatmap
%{"a.b.c": 42, "a.b.d.0": nil, "a.b.d.1": 42, "a.e.0": :f, "a.e.1": 42}Lists are handled gracefully, index is used as a key in resulting map.
Parameters
- input: nested map/list/keyword/struct to be flattened,
- opts: the additional options to be passed through: —- delimiter(default:- ".",) might be passed explicitly or configured with- :iteraptor, :delimiterapplication setting.
Examples
iex> [:a, 42] |> Iteraptor.to_flatmap
%{0 => :a, 1 => 42}
iex> %{a: 42} |> Iteraptor.to_flatmap
%{a: 42}
iex> %{a: 42, b: 42} |> Iteraptor.to_flatmap
%{a: 42, b: 42}
iex> %{a: %{b: 42}, d: 42} |> Iteraptor.to_flatmap
%{"a.b" => 42, d: 42}
iex> %{a: [:b, 42], d: 42} |> Iteraptor.to_flatmap
%{"a.0" => :b, "a.1" => 42, d: 42}
iex> %{a: %{b: [:c, 42]}, d: 42} |> Iteraptor.to_flatmap
%{"a.b.0" => :c, "a.b.1" => 42, d: 42}
iex> %{a: %{b: 42}} |> Iteraptor.to_flatmap
%{"a.b" => 42}
iex> %{a: %{b: %{c: 42}}} |> Iteraptor.to_flatmap
%{"a.b.c" => 42}
iex> %{a: %{b: %{c: 42}}, d: 42} |> Iteraptor.to_flatmap
%{"a.b.c" => 42, d: 42}
iex> [a: [b: [c: 42]], d: 42] |> Iteraptor.to_flatmap
%{"a.b.c" => 42, d: 42}
iex> [a: [[:b], 42], d: 42] |> Iteraptor.to_flatmap
%{"a.0.0" => :b, "a.1" => 42, d: 42}
iex> %{a: %{b: %{c: 42, d: [nil, 42]}, e: [:f, 42]}} |> Iteraptor.to_flatmap
%{"a.b.c" => 42, "a.b.d.0" => nil, "a.b.d.1" => 42, "a.e.0" => :f, "a.e.1" => 42}
iex> %{a: %{b: %{c: 42, d: [nil, 42]}, e: [:f, 42]}}
...> |> Iteraptor.to_flatmap(delimiter: "_")
%{"a_b_c" => 42, "a_b_d_0" => nil, "a_b_d_1" => 42, "a_e_0" => :f, "a_e_1" => 42}