plymio_funcio v0.1.0 Plymio.Funcio.Enum.Select View Source

Selecting Specific Elements from an Enum.

See Plymio.Funcio for overview and documentation terms.

Link to this section Summary

Functions

filter_enum/2 takes a enum as its first argument

filter_with_index_enum/2 takes an enum and a index tuple predicate/1

reject_enum/2 takes a enum as its first argument

reject_with_index_enum/2 takes an enum and a index tuple predicate/1

Link to this section Types

Link to this section Functions

Link to this function filter_enum(enum, filter_or_index_range) View Source
filter_enum(any(), any()) ::
  {:ok, list()} | {:ok, stream()} | {:error, error()}

filter_enum/2 takes a enum as its first argument.

If the second argument is a predicate/1, it filters the enum (Stream.filter/2) returning {:ok, stream}.

Otherwise the second argument is assumed to be a index range and Plymio.Funcio.Enum.ValueAt.fetch_value_at_enum/2 is called.

Note: the filtered list is returned in the order of the indices (so out of order and duplicates are allowed)

Examples

iex> {:ok, stream} = [1,2,3] |> filter_enum(&is_integer/1)
...> stream |> Enum.to_list
[1,2,3]

iex> {:ok, stream} = [1,2,3] |> filter_enum(0)
...> stream |> Enum.to_list
[1]

iex> {:ok, stream} = [1,2,3] |> filter_enum([-1, -2, 0, 1, 2])
...> stream |> Enum.to_list
[3, 2, 1, 2, 3]

iex> {:ok, stream} = [1,2,3] |> filter_enum(nil)
...> stream |> Enum.to_list
[1, 2, 3]

iex> {:ok, stream} = [1,:b,3] |> filter_enum(&is_integer/1)
...> stream |> Enum.to_list
[1,3]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> filter_enum(fn {_k,v} -> is_integer(v) end)
...> stream |> Enum.to_list
[a: 1, b: 2, c: 3]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> filter_enum([
...>      fn {_k,v} -> is_integer(v) end,
...>      fn {_k,v} -> v > 1 end,
...> ])
...> stream |> Enum.to_list
[b: 2, c: 3]

iex> {:ok, stream} = %{:a => 1, :b => 2, "c" => 3}
...> |> filter_enum(fn {k,_v} -> is_atom(k) end)
...> stream |> Enum.to_list
[a: 1, b: 2]

iex> {:ok, stream} = 42 |> filter_enum(&(&1))
...> try do
...>   stream |> Enum.to_list
...> rescue
...>   error -> error
...> end
...> |> Exception.message
...> |> String.starts_with?("protocol Enumerable not implemented for 42")
true

iex> {:error, error} = [1,2,3] |> filter_enum(:not_a_fun)
...> error |> Exception.message
"index range invalid, got: :not_a_fun"
Link to this function filter_with_index_enum(enum, filter) View Source
filter_with_index_enum(any(), any()) ::
  {:ok, list()} | {:ok, stream()} | {:error, error()}

filter_with_index_enum/2 takes an enum and a index tuple predicate/1.

It first passes the enum through Stream.with_index/1 before calling Stream.filter/2. The index tuple predicate/1 is called with a 2tuple: {value, index} and, if the return is truthy, the 2tuple is used as the result.

On sucess, the result will be {:ok, stream} where stream is a Stream.

Examples

iex> {:ok, stream} = [:a,:b,:c]
...> |> filter_with_index_enum(fn {v,_i} -> is_atom(v) end)
...> stream |> Enum.to_list
[{:a, 0}, {:b, 1}, {:c, 2}]

iex> {:ok, stream} = [:a,:b,:c]
...> |> filter_with_index_enum(fn {_v,i} -> i > 0 end)
...> stream |> Enum.to_list
[{:b, 1}, {:c, 2}]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> filter_with_index_enum([
...>      fn {{_k,v}, _i} -> is_integer(v) end,
...>      fn {{_k,v}, _i} -> v > 1 end,
...>      fn {{_k,_v}, i} -> i > 1 end,
...> ])
...> stream |> Enum.to_list
[{{:c, 3}, 2}]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> filter_with_index_enum(fn {{_k,_v},i} -> i > 1 end)
...> stream |> Enum.to_list
[{{:c, 3}, 2}]

iex> {:ok, stream} = %{:a => 1, :b => 2, "c" => 3}
...> |> filter_with_index_enum(fn {{k,_v}, _i} -> is_atom(k) end)
...> stream |> Enum.to_list
[{{:a, 1}, 0}, {{:b, 2}, 1}]

iex> {:ok, stream} = 42 |> filter_with_index_enum(&(&1))
...> try do
...>   stream |> Enum.to_list
...> rescue
...>   error -> error
...> end
...> |> Exception.message
...> |> String.starts_with?("protocol Enumerable not implemented for 42")
true

iex> {:error, error} = [1,2,3] |> filter_with_index_enum(:not_a_fun)
...> error |> Exception.message
"predicate/1 function invalid, got: :not_a_fun"
Link to this function reject_enum(enum, filter_or_index_range) View Source
reject_enum(any(), any()) ::
  {:ok, list()} | {:ok, stream()} | {:error, error()}

reject_enum/2 takes a enum as its first argument.

If the second argument is a predicate/1, it rejects the enum (Stream.reject/2) returning {:ok, stream}.

Otherwise the second argument is assumed to be a index range and Plymio.Funcio.Enum.ValueAt.delete_value_at_enum/2 is called.

Examples

iex> {:ok, stream} = [1,2,3] |> reject_enum(&is_integer/1)
...> stream |> Enum.to_list
[]

iex> {:ok, stream} = [1,2,3] |> reject_enum(0)
...> stream |> Enum.to_list
[2, 3]

iex> {:ok, stream} = [1,2,3] |> reject_enum([-1, -2, 0, 1, 2])
...> stream |> Enum.to_list
[]

iex> {:ok, stream} = [1,:b,3] |> reject_enum(&is_integer/1)
...> stream |> Enum.to_list
[:b]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> reject_enum(fn {_k,v} -> v > 2 end)
...> stream |> Enum.to_list
[a: 1, b: 2]

iex> {:ok, stream} = %{:a => 1, :b => 2, "c" => 3}
...> |> reject_enum(fn {k,_v} -> is_atom(k) end)
...> stream |> Enum.to_list
[{"c", 3}]

iex> {:ok, stream} = 42 |> reject_enum(&(&1))
...> try do
...>   stream |> Enum.to_list
...> rescue
...>   error -> error
...> end
...> |> Exception.message
...> |> String.starts_with?("protocol Enumerable not implemented for 42")
true

iex> {:error, error} = [1,2,3] |> reject_enum(:not_a_fun)
...> error |> Exception.message
"index range invalid, got: :not_a_fun"
Link to this function reject_with_index_enum(enum, filter) View Source
reject_with_index_enum(any(), any()) :: {:ok, list()} | {:error, error()}

reject_with_index_enum/2 takes an enum and a index tuple predicate/1.

It first passes the enum through Stream.with_index/1 before calling Enum.reject/2.

The index tuple predicate/1 is called with a 2tuple: {value, index} and, if the return is truthy, the 2tuple is rejected.

On sucess, the result will be {:ok, stream} where stream is a Stream.

Examples

iex> {:ok, stream} = [1,2,3]
...> |> reject_with_index_enum(fn {v,_i} -> is_integer(v) end)
...> stream |> Enum.to_list
[]

iex> {:ok, stream} = [1,:b,3]
...> |> reject_with_index_enum(fn {v,_i} -> is_integer(v) end)
...> stream |> Enum.to_list
[{:b, 1}]

iex> {:ok, stream} = [a: 1, b: 2, c: 3]
...> |> reject_with_index_enum(fn {{_k,_v}, i} -> i > 1 end)
...> stream |> Enum.to_list
[{{:a, 1}, 0}, {{:b, 2}, 1}]

iex> {:ok, stream} = %{:a => 1, :b => 2, "c" => 3}
...> |> reject_with_index_enum(fn {{k,_v}, _i} -> is_atom(k) end)
...> stream |> Enum.to_list
[{{"c", 3}, 2}]

iex> {:ok, stream} = 42 |> reject_with_index_enum(&(&1))
...> try do
...>   stream |> Enum.to_list
...> rescue
...>   error -> error
...> end
...> |> Exception.message
...> |> String.starts_with?("protocol Enumerable not implemented for 42")
true

iex> {:error, error} = [1,2,3] |> reject_with_index_enum(:not_a_fun)
...> error |> Exception.message
"predicate/1 function invalid, got: :not_a_fun"