Iteraptor
Handy enumerable operations
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;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;use Iteraptor.Iteraptableto automagically implementEnumerableandCollectableprotocols, as well asAccessbehaviour on the structure.
bonus:
Iteraptor.Extras.bury/4to store the value deeply inside nested term (the intermediate keys are created as necessary.)
HexDocs
Usage
Iterating, Mapping, Reducing
# each
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}}}
# map
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"}}
# reduce
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"]
# map-reduce
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: 42}}}, ["a.b.c=", "a.b", "a"]}Flattening
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}
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]}}Extras
iex> Iteraptor.Extras.bury([foo: :bar], ~w|a b c d|a, 42)
[a: [b: [c: [d: 42]]], foo: :bar]Installation
Add iteraptor to your list of dependencies in mix.exs:
def deps, do: [{:iteraptor, "~> 1.0.0-rc1"}]Changelog
1.0.0-rc1
Better documentation, Iteraptor.Extras.bury/3.
0.9.0
Complete refactoring, Iteraptor.map/3, Iteraptor.reduce/4, Iteraptor.map_reduce/4.
0.5.0
NB: This functionality is experimental and might not appear in 1.0.0 release.
use Iteraptor.Iteraptable inside structs to make them both
Enumerable and
Collectable:
defmodule Iteraptor.Struct do
@fields [field: nil]
def fields, do: @fields
defstruct @fields
use Iteraptor.Iteraptable
end
iex> %Iteraptor.Struct{field: 42}
...> |> Enum.each(fn e -> IO.inspect(e) end)
#⇒ {:field, 42}0.4.0
Experimental: support for structs on input.
Structs will be automagically created on |> Iteraptor.from_flatmap from
keys like StructName%field if a) this structure is known to the system
and b) keys are consistent (e. g. there are no subsequent elements,
belonging to different structs: ["S1%f" => 42, "S2%f" => 3.14].)
0.3.0
Support for Keyword on input,
but it will be output as map for |> Iteraptor.to_flatmap |> Iteraptor.from_flatmap
back and forth transformation.