README
REnum
REnum is Enum extended with convenient functions inspired by Ruby and Rails ActiveSupport. It also provides full support for native functions through metaprogramming. In addition to REnum, modules such as RList, RMap, RRange can also be used.
Installation
def deps do
[
{:r_enum, "~> 0.6"}
]
end
For the full list of available functions, see API Reference.
About REnum
All the functions are available defined in
compact/1
Returns an list of all non-nil elements.
iex> REnum.compact([1, nil, 2, 3])
[1, 2, 3]
# See also REnum.ActiveSupport.compact_blank
each_slice/2
Returns Stream given enumerable sliced by each amount.
iex> ["a", "b", "c", "d", "e"]
iex> |> REnum.each_slice(2)
iex> |> Enum.to_list()
[["a", "b"], ["c", "d"], ["e"]]
grep/2
Returns elements selected by a given pattern or function.
iex> ["foo", "bar", "car", "moo"]
iex> |> REnum.grep(~r/ar/)
["bar", "car"]
iex> 1..10
iex> |> REnum.grep(3..8)
[3, 4, 5, 6, 7, 8]
reverse_each/2
Calls the function with each element, but in reverse order; returns given enumerable.
iex> REnum.reverse_each([1, 2, 3], &IO.inspect(&1))
# 3
# 2
# 1
[1, 2, 3]
pluck/2
Extract the given key from each element in the enumerable.
iex> payments = [
...> %Payment{dollars: 5, cents: 99},
...> %Payment{dollars: 10, cents: 0},
...> %Payment{dollars: 0, cents: 5}
...> ]
iex> REnum.pluck(payments, [:dollars, :cents])
[[5, 99], [10, 0], [0, 5]]
iex> REnum.pluck(payments, :dollars)
[5, 10, 0]
iex> REnum.pluck([], :dollars)
[]
exclude?/2
The negative of the Enum.member?
.Returns true+if the collection does not include the object.
iex> REnum.exclude?([2], 1)
true
iex> REnum.exclude?([2], 2)
false
# See also REnum.ActiveSupport.include?
without/2
Returns enumerable excluded the specified elements.
iex> REnum.without(1..5, [1, 5])
[2, 3, 4]
iex> REnum.without(%{foo: 1, bar: 2, baz: 3}, [:bar])
%{foo: 1, baz: 3}
# See also REnum.ActiveSupport.including
many?/2
Returns true if the enumerable has more than 1 element.
iex> REnum.many?([])
false
iex> REnum.many?([1])
false
iex> REnum.many?([1, 2])
true
iex> REnum.many?(%{})
false
iex> REnum.many?(%{a: 1})
false
iex> REnum.many?(%{a: 1, b: 2})
true
list_and_not_keyword?/1
Returns true if argument is list and not keyword list.
iex> REnum.list_and_not_keyword?([1, 2, 3])
true
iex> REnum.list_and_not_keyword?([a: 1, b: 2])
false
map_and_not_range?/1
Returns true if argument is map and not range.
iex> REnum.map_and_not_range?(%{})
true
iex> REnum.map_and_not_range?(1..3)
false
About RList
RList is List extended with convenient functions inspired by Ruby and Rails ActiveSupport. All the functions are available defined in
push/2
Appends trailing elements.
iex> [:foo, 'bar', 2]
iex> |> RList.push([:baz, :bat])
[:foo, 'bar', 2, :baz, :bat]
iex> [:foo, 'bar', 2]
iex> |> RList.push(:baz)
[:foo, 'bar', 2, :baz]
# See also REnum.Ruby.shift, REnum.Ruby.pop, REnum.Ruby.unshift
combination/2
Returns Stream that is each repeated combinations of elements of given list. The order of combinations is indeterminate.
iex> RList.combination([1, 2, 3, 4], 1)
iex> |> Enum.to_list()
[[1],[2],[3],[4]]
iex> RList.combination([1, 2, 3, 4], 3)
iex> |> Enum.to_list()
[[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
iex> RList.combination([1, 2, 3, 4], 0)
iex> |> Enum.to_list()
[[]]
iex> RList.combination([1, 2, 3, 4], 5)
iex> |> Enum.to_list()
[]
# See also RList.Ruby.repeated_combination, RList.Ruby.permutation, RList.Ruby.repeated_permutation
fill/3
Fills the list with the provided value. The filler can be either a function or a fixed value.
iex> RList.fill(~w[a b c d], "x")
["x", "x", "x", "x"]
iex> RList.fill(~w[a b c d], "x", 0..1)
["x", "x", "c", "d"]
iex> RList.fill(~w[a b c d], fn _, i -> i * i end)
[0, 1, 4, 9]
iex> RList.fill(~w[a b c d], fn _, i -> i * 2 end, 0..1)
[0, 2, "c", "d"]
dig/3
Finds and returns the element in nested elements that is specified by index and identifiers.
iex> [:foo, [:bar, :baz, [:bat, :bam]]]
iex> |> RList.dig(1)
[:bar, :baz, [:bat, :bam]]
iex> [:foo, [:bar, :baz, [:bat, :bam]]]
iex> |> RList.dig(1, [2])
[:bat, :bam]
iex> [:foo, [:bar, :baz, [:bat, :bam]]]
iex> |> RList.dig(1, [2, 0])
:bat
iex> [:foo, [:bar, :baz, [:bat, :bam]]]
iex> |> RList.dig(1, [2, 3])
nil
intersection/2
Returns a new list containing each element found both in list1 and in all of the given list2; duplicates are omitted.
iex> [1, 2, 3]
iex> |> RList.intersection([3, 4, 5])
[3]
iex> [1, 2, 3]
iex> |> RList.intersection([5, 6, 7])
[]
iex> [1, 2, 3]
iex> |> RList.intersection([1, 2, 3])
[1, 2, 3]
"""
sample/2
Returns one or more random elements.
values_at/1
Returns a list containing the elements in list corresponding to the given selector(s).The selectors may be either integer indices or ranges.
iex> RList.values_at(~w[a b c d e f], [1, 3, 5])
["b", "d", "f"]
iex> RList.values_at(~w[a b c d e f], [1, 3, 5, 7])
["b", "d", "f", nil]
iex> RList.values_at(~w[a b c d e f], [-1, -2, -2, -7])
["f", "e", "e", nil]
iex> RList.values_at(~w[a b c d e f], [4..6, 3..5])
["e", "f", nil, "d", "e", "f"]
iex> RList.values_at(~w[a b c d e f], 4..6)
["e", "f", nil]
second/1
Equal to Enum.at(list, 1)
.
iex> ~w[a b c d]
iex> |> RList.second()
"b"
# See also RList.ActiveSupport.third, RList.ActiveSupport.fourth, RList.ActiveSupport.fifth and RList.ActiveSupport.forty_two
from/2
Returns the tail of the list from position.
iex> ~w[a b c d]
iex> |> RList.from(0)
["a", "b", "c", "d"]
iex> ~w[a b c d]
iex> |> RList.from(2)
["c", "d"]
iex> ~w[a b c d]
iex> |> RList.from(10)
[]
iex> ~w[]
iex> |> RList.from(0)
[]
iex> ~w[a b c d]
iex> |> RList.from(-2)
["c", "d"]
iex> ~w[a b c d]
iex> |> RList.from(-10)
[]
# See also RList.ActiveSupport.to
to_sentence/2
Converts the list to a comma-separated sentence where the last element is joined by the connector word.
You can pass the following options to change the default behavior. If you pass an option key that doesn't exist in the list below, it will raise an
Options
:words_connector
- The sign or word used to join all but the last element in lists with three or more elements (default: ", ").:last_word_connector
- The sign or word used to join the last element in lists with three or more elements (default: ", and ").:two_words_connector
- The sign or word used to join the elements in lists with two elements (default: " and ").
iex> ["one", "two"]
iex> |> RList.to_sentence()
"one and two"
iex> ["one", "two", "three"]
iex> |> RList.to_sentence()
"one, two, and three"
iex> ["one", "two"]
iex> |> RList.to_sentence(two_words_connector: "-")
"one-two"
iex> ["one", "two", "three"]
iex> |> RList.to_sentence(words_connector: " or ", last_word_connector: " or at least ")
"one or two or at least three"
iex> ["one", "two", "three"]
iex> |> RList.to_sentence()
"one, two, and three"
new/2
Make a list of size amount.
iex> 1
iex> |> RList.new(3)
[1, 1, 1]
About RMap
RMap is Map extended with convenient functions inspired by Ruby and Rails ActiveSupport. All the functions are available defined in
dig/2
Returns the object in nested map that is specified by a given key and additional arguments.
iex> RMap.dig(%{a: %{b: %{c: 1}}}, [:a, :b, :c])
1
iex> RMap.dig(%{a: %{b: %{c: 1}}}, [:a, :c, :b])
nil
each_key/2
Calls the function with each key; returns :ok.
iex> RMap.each_key(%{a: 1, b: 2, c: 3}, &IO.inspect(&1))
# :a
# :b
# :c
:ok
# See also RMap.Ruby.each_value, RMap.Ruby.each_pair
except/2
Returns a map excluding entries for the given keys.
iex> RMap.except(%{a: 1, b: 2, c: 3}, [:a, :b])
%{c: 3}
invert/1
Returns a map object with the each key-value pair inverted.
iex> RMap.invert(%{"a" => 0, "b" => 100, "c" => 200, "d" => 300, "e" => 300})
%{0 => "a", 100 => "b", 200 => "c", 300 => "e"}
iex> RMap.invert(%{a: 1, b: 1, c: %{d: 2}})
%{1 => :b, %{d: 2} => :c}
values_at/2
Returns a list containing values for the given keys.
iex> RMap.values_at(%{a: 1, b: 2, c: 3}, [:a, :b, :d])
[1, 2, nil]
deep_atomize_keys/1
Returns a list with all keys converted to atom. This includes the keys from the root map and from all nested maps and arrays.
iex> RMap.deep_atomize_keys(%{"name" => "Rob", "years" => "28", "nested" => %{ "a" => 1 }})
%{name: "Rob", nested: %{a: 1}, years: "28"}
iex> RMap.deep_atomize_keys(%{"a" => %{"b" => %{"c" => 1}, "d" => [%{"a" => 1, "b" => %{"c" => 2}}]}})
%{a: %{b: %{c: 1}, d: [%{a: 1, b: %{c: 2}}]}}
# See also RList.ActiveSupport.deep_symbolize_keys, RList.ActiveSupport.symbolize_keys, RList.ActiveSupport.deep_stringify_keys, RList.ActiveSupport.stringify_keys,
deep_transform_keys/2
Returns a list with all keys converted to atom. This includes the keys from the root map and from all nested maps and arrays.
iex> RMap.deep_transform_keys(%{a: %{b: %{c: 1}}}, &to_string(&1))
%{"a" => %{"b" => %{"c" => 1}}}
iex> RMap.deep_transform_keys(%{a: %{b: %{c: 1}, d: [%{a: 1, b: %{c: 2}}]}}, &inspect(&1))
%{":a" => %{":b" => %{":c" => 1}, ":d" => [%{":a" => 1, ":b" => %{":c" => 2}}]}}
# See also RList.ActiveSupport.deep_transform_values
About RRange
All the functions are available defined in
begin/1
Returns the first element of range.
iex> RList.begin(1..3)
1
# See also RRange.Ruby.end
step/2
Returns Stream that from given range split into by given step.
iex> RList.step(1..10, 2)
iex> |> Enum.to_list()
[1, 3, 5, 7, 9]
"""
overlaps?/2
Compare two ranges and see if they overlap each other.
iex> RList.overlaps?(1..5, 4..6)
true
iex> RList.overlaps?(1..5, 7..9)
false
About RUtils
Some useful functions.
blank?/1
Return true if object is blank, false, empty, or a whitespace string. For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
iex> RUtils.blank?(%{})
true
iex> RUtils.blank?([1])
false
iex> RUtils.blank?(" ")
true
present?/1
Returns true if not RUtils.blank?
iex> RUtils.present?(%{})
false
iex> RUtils.present?([1])
true
iex> RUtils.present?(" ")
false
define_all_functions!/2
Defines in the module that called all the functions of the argument module.
iex> defmodule A do
...> defmacro __using__(_opts) do
...> RUtils.define_all_functions!(__MODULE__)
...> end
...>
...> def test do
...> :test
...> end
...> end
iex> defmodule B do
...> use A
...> end
iex> B.test
:test
Progress
REnum | Elixir Module | Ruby Class | Elixir | Ruby | ActiveSupport |
---|---|---|---|---|---|
REnum | Enum | Enumerable | ✅ | ✅ | ✅ |
RList | List | Array | ✅ | ✅ | ✅ |
RMap | Map | Hash | ✅ | ✅ | ✅ |
RRange | Range | Range | ✅ | ✅ | ✅ |
RStream | Stream | Enumerator::Lazy | ✅ | TODO | TODO |