iteraptor v1.2.1 Iteraptor View Source

Iteraptor makes complicated nested structures (currently Maps, Lists and Keywords) iteration easier.

Usage

Iterating, Mapping, Reducing

Flattening

Filtering

  • Iteraptor.filter/3 to filter the structure according to the value returned from each iteration (true to leave the element, false to discard.)

Link to this section Summary

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

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

Link to this section Functions

Link to this function each(input, fun, opts \\ []) View Source
each(
  %{} | Keyword.t() | [...] | Access.t(),
  ({any(), any()} -> any()),
  Keyword.t()
) :: %{} | Keyword.t() | [...] | 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 key is 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 | :maps | :keywords | what to yield; default: nil for yielding values only.

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}}}
Link to this function filter(input, fun, opts \\ []) View Source
filter(
  %{} | Keyword.t() | [...] | Access.t(),
  ({any(), any()} -> any()),
  Keyword.t()
) :: {%{} | Keyword.t() | [...] | Access.t(), any()}

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

    • yield: [:all | :maps | :keywords | what to yield; default: nil for yielding values only.

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}
Link to this function from_flatmap(input, transformer \\ nil, opts \\ []) View Source
from_flatmap(%{}, ({any(), any()} -> any()) | nil, Keyword.t()) ::
  %{} | [...] | Keyword.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}]
Link to this function map(input, fun, opts \\ []) View Source
map(
  %{} | Keyword.t() | [...] | Access.t(),
  ({any(), any()} -> any()),
  Keyword.t()
) :: %{} | Keyword.t() | [...] | 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 key is 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 | :maps | :keywords | what to yield; default: nil for yielding values only.

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"}}
Link to this function map_reduce(input, acc \\ %{}, fun, opts \\ []) View Source
map_reduce(
  %{} | Keyword.t() | [...] | Access.t(),
  %{} | Keyword.t() | [...] | Access.t(),
  ({any(), any()}, any() -> any()),
  Keyword.t()
) :: {%{} | Keyword.t() | [...] | Access.t(), any()}

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}, acc pair, where key is an array or deeply nested keys, value is the value and acc is the accumulator;
  • opts: the options to be passed to the iteration

    • yield: [:all | :maps | :keywords | what to yield; default: nil for yielding values only.

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"]}
Link to this function reduce(input, acc \\ nil, fun, opts \\ []) View Source
reduce(
  %{} | Keyword.t() | [...] | Access.t(),
  %{} | Keyword.t() | [...] | Access.t(),
  ({any(), any()}, any() -> any()),
  Keyword.t()
) :: {%{} | Keyword.t() | [...] | Access.t(), any()}

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}, acc pair, where key is an array or deeply nested keys, value is the value and acc is the accumulator;
  • opts: the options to be passed to the iteration

    • yield: [:all | :maps | :keywords | what to yield; default: nil for yielding values only.

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"]
Link to this function to_flatmap(input, opts \\ []) View Source
to_flatmap(%{} | [...], Keyword.t()) :: %{}

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, :delimiter application 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}