Packages
iteraptor
1.10.3
1.15.0
1.14.0
1.13.1
1.13.0
1.12.2
1.12.1
1.12.0
1.11.0
1.10.3
1.10.2
1.10.1
1.9.0
1.8.0
1.7.3
1.7.2
1.7.1
1.7.0
1.6.1
1.6.0
1.4.1
1.4.0
1.3.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc1
0.7.0
0.6.2
0.6.1
0.5.2
0.5.1
0.5.0
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.1.1
0.1.0
This small library allows the deep iteration / mapping of Enumerables.
Current section
Files
Jump to
Current section
Files
README.md
# Iteraptor
[](https://travis-ci.org/am-kantox/elixir-iteraptor)
[](http://inch-ci.org/github/am-kantox/elixir-iteraptor)
[](https://hex.pm/packages/iteraptor)
### Handy enumerable operations
* [`Iteraptor.each/3`](https://hexdocs.pm/iteraptor/Iteraptor.html#each/3)
to iterate a deeply nested map/list/keyword;
* [`Iteraptor.map/3`](https://hexdocs.pm/iteraptor/Iteraptor.html#map/3)
to map a deeply nested map/list/keyword;
* [`Iteraptor.reduce/4`](https://hexdocs.pm/iteraptor/Iteraptor.html#reduce/4)
to reduce a deeply nested map/list/keyword;
* [`Iteraptor.map_reduce/4`](https://hexdocs.pm/iteraptor/Iteraptor.html#map_reduce/4)
to map and reduce a deeply nested map/list/keyword;
* [`Iteraptor.filter/3`](https://hexdocs.pm/iteraptor/Iteraptor.html#filter/3)
to filter a deeply nested map/list/keyword;
* [`Iteraptor.to_flatmap/2`](https://hexdocs.pm/iteraptor/Iteraptor.html#to_flatmap/2)
to flatten a deeply nested map/list/keyword into
flatten map with concatenated keys;
* [`Iteraptor.from_flatmap/3`](https://hexdocs.pm/iteraptor/Iteraptor.html#from_flatmap/3)
to “unveil”/“unflatten” the previously flattened map into nested structure;
* [`use Iteraptor.Iteraptable`](https://hexdocs.pm/iteraptor/Iteraptor.Iteraptable.html)
to automagically implement `Enumerable` and `Collectable` protocols, as well as
`Access` behaviour on the structure.
**bonus:**
* [`Iteraptor.jsonify/2`](https://hexdocs.pm/iteraptor/Iteraptor.html#jsonify/2) to prepare the term for JSON interchange; it basically converts keys to strings and keywords to maps because JSON encoders might have issues with serializing keywords.
* [`Iteraptor.Extras.bury/4`](https://hexdocs.pm/iteraptor/Iteraptor.Extras.html#bury/4)
to store the value deeply inside nested term (the intermediate keys are created as
necessary.)
### HexDocs
* [API Reference](https://hexdocs.pm/iteraptor/api-reference.html)
* [`Iteraptor`](https://hexdocs.pm/iteraptor/Iteraptor.html)
* [`Iteraptor.Iteraptable`](https://hexdocs.pm/iteraptor/Iteraptor.Iteraptable.html)
### Usage
#### Iterating, Mapping, Reducing
```elixir
# 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"]}
# filter
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}
```
#### Flattening
```elixir
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
```elixir
iex> Iteraptor.jsonify([foo: [bar: [baz: :zoo], boo: 42]], values: true)
%{"foo" => %{"bar" => %{"baz" => "zoo"}, "boo" => 42}}
iex> Iteraptor.Extras.bury([foo: :bar], ~w|a b c d|a, 42)
[a: [b: [c: [d: 42]]], foo: :bar]
```
**As of version `1.2.0` there is an experimental AST traversal feature:
```elixir
iex> Iteraptor.AST.reduce((quote do: 42), [], fn e, acc -> [e | acc], yield: :all)
'*'
```
---
### Installation
Add `iteraptor` to your list of dependencies in `mix.exs`:
```elixir
def deps, do: [{:iteraptor, "~> 1.5"}]
```
### Changelog
#### `1.10.0`
`Iteraptor.jsonify/2` for deep conversion of keyword lists to maps.
#### `1.8.0`
`Iteraptor.Config` for deep substitution of `{:system, "VAR"}` tuples with the
values taken from the system environment in runtime.
#### `1.7.0`
`Iteraptor.Array` with `Access` support. Basically, `Array` is the list with `Access` support.
- `1.7.2` → fixed bug with type recognition for `MapSet` and `Iteraptor.Array`.
#### `1.6.0`
`Iteraptor.jsonify/2`.
#### `1.5.0`
All iterators do now accept `structs: :values` keyword argument to prevent nested iteration into structs.
Experimental support for `Iteraptable` protocol.
#### `1.4.0`
Extended support for `Iteraptor.Iteraptable`:
#### `1.3.0`
We now support `MapSet`s.
#### `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`](http://elixir-lang.org/docs/stable/elixir/Enumerable.html) and
[`Collectable`](http://elixir-lang.org/docs/stable/elixir/Collectable.html):
```elixir
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](http://elixir-lang.org/getting-started/structs.html) 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`](http://elixir-lang.org/docs/stable/elixir/Keyword.html) on input,
but it will be output as map for `|> Iteraptor.to_flatmap |> Iteraptor.from_flatmap`
back and forth transformation.