Morphix (morphix v0.8.1)

Morphix provides convenience methods for dealing with Maps, Lists, and Tuples.

morphiflat/1 and morphiflat!/1 flatten maps, discarding top level keys.

Examples:

iex> Morphix.morphiflat %{flatten: %{this: "map"}, if: "you please"}
{:ok, %{this: "map", if: "you please"}}

iex> Morphix.morphiflat! %{flatten: %{this: "map"}, o: "k"}
%{this: "map", o: "k"}

morphify!/2 and morphify/2 will take either a List or a Tuple as the first argument, and a function as the second. Returns a map, with the keys of the map being the function applied to each member of the input.

Examples:

iex> Morphix.morphify!({[1,2,3], [12], [1,2,3,4]}, &length/1)
%{1 => [12], 3 => [1,2,3], 4 => [1,2,3,4]}

atomorphify/1 and atomorphiform/1 take a map as an input and return the map with all string keys converted to atoms. atomorphiform/1 is recursive. atomorphiform/2 and atomormiphify/2 take :safe as a second argument, they will not convert string keys if the resulting atom has not been defined.

Examples:

iex> Morphix.atomorphify(%{"a" => "2", :a => 2, 'a'  => :two})
{:ok, %{:a => 2, 'a' => :two }}

compactify and compactiform take a map or list as an input and returns a filtered map or list, removing any keys or elements with nil values or with an empty map as a value.

partiphify!/2 and partiphify/2 take a list l and an integer k and partition l into k sublists of balanced size. There will always be k lists, even if some must be empty.

Examples:

iex> Morphix.partiphify!([:a, :b, :c, :d, :e, :f], 4)
[[:c], [:d], [:e, :a], [:f, :b]]

iex> Morphix.partiphify!([:a, :b, :c, :d, :e], 4)
[[:b], [:c], [:d], [:e, :a]]

iex> Morphix.partiphify!([:a, :b, :c, :d], 4)
[[:a], [:b], [:c], [:d]]

iex> Morphix.partiphify!([:a, :b, :c], 4)
[[:a], [:b], [:c], []]

equaliform?/2 compares two ordered or unordered lists and returns true if they are equal. It also handles nested elements.

Example:

iex> Morphix.equaliform?([1, ["two", :three], %{a: 1, c: "three", e: %{d: 4, b: 2}}], [[:three, "two"], 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
true

equalify?/2 compares two ordered or unordered lists and returns true if they are equal.

Example:

iex> Morphix.equalify?([1, ["two", :three], %{a: 1, c: "three", e: %{d: 4, b: 2}}], [["two", :three], 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
true

Link to this section Summary

Functions

Takes a map as an argument and returns {:ok, map}, with all string keys (including keys in nested maps) converted to atom keys.

Takes a map and a list of allowed strings as arguments and returns {:ok, map}, with any strings that are in the list converted to atoms, and any strings that are not in the list left as strings.

Takes a map as an argument and returns the same map, with all string keys (including keys in nested maps) converted to atom keys.

Takes a map and a list of allowed strings as arguments and returns the same map, with any strings that are in the list converted to atoms, and any strings that are not in the list left as strings.

Takes a map as an argument and returns {:ok, map}, with string keys converted to atom keys. Does not examine nested maps.

Takes a map and a list of allowed strings to convert to atoms and returns {:ok, map}, with string keys in the list converted to atoms. Ignores nested maps.

Takes a map as an argument and returns the same map with string keys converted to atom keys. Does not examine nested maps.

Takes a map and a list of allowed strings to convert to atoms and returns the same map, with string keys in the list converted to atoms. Ignores nested maps.

Removes keys with nil values from maps and nil elements from lists. It also handles nested maps and lists, and treats empty maps as nil values.

Removes keys with nil values from nested maps, eliminates empty maps, and removes nil values from nested lists.

Takes a map or a list and removes any keys or elements that have nil values.

Takes a map or list and removes keys or elements that have nil values, or are empty maps.

Takes two elements and returns true if they are equal, ignoring order for Enumerables. Order is also ignored for nested Enumerables.

Takes two elements and returns true if they are equal, ignoring order for Enumerables. Order is not ignored for nested Enumerables.

Takes a map and returns a flattened version of that map. If the map has nested maps (or the maps nested maps have nested maps, etc.) morphiflat moves all nested key/value pairs to the top level, discarding the original keys.

Takes a map and returns a flattend version of that map, discarding any nested keys.

Takes a map and a function as an argument and returns the same map, with all keys transformed by the function.(including keys in nested maps) converted to atom keys.

Takes a List and a function as arguments and returns {:ok, Map}, with the keys of the map the result of applying the function to each item in the list.

Takes a list and a function as arguments and returns a Map, with the keys of the map the result of applying the function to each item in the list.

Divides a list into k distinct sub-lists, with partitions being as close to the same size as possible

Divides a list into k distinct sub-lists, with partitions being as close to the same size as possible

Takes a map as an argument and returns the same map with atom keys converted to string keys. Does not examine nested maps.

Takes a map and a list of allowed atoms as arguments and returns the same map, with any atoms that are in the list converted to strings, and any atoms that are not in the list left as atoms.

Link to this section Functions

Link to this function

atomorphiform(map)

Specs

atomorphiform(map()) :: {:ok, map()}

Takes a map as an argument and returns {:ok, map}, with all string keys (including keys in nested maps) converted to atom keys.

Examples:

iex> Morphix.atomorphiform(%{:this => %{map: %{"has" => "a", :nested => "string", :for =>  %{a: :key}}}, "the" =>  %{"other" => %{map: :does}}, as: "well"})
{:ok,%{this: %{map: %{has: "a", nested: "string", for: %{a: :key}}}, the: %{other: %{map: :does}}, as: "well"} }

iex> Morphix.atomorphiform(%{"this" => ["map", %{"has" => ["a", "list"]}], "inside" => "it"})
{:ok, %{this: ["map", %{has: ["a", "list"]}], inside: "it"}}
Link to this function

atomorphiform(map, allowed)

Specs

atomorphiform(map(), :safe) :: {:ok, map()}
atomorphiform(map(), list()) :: {:ok, map()}

Takes a map and a list of allowed strings as arguments and returns {:ok, map}, with any strings that are in the list converted to atoms, and any strings that are not in the list left as strings.

Works recursively on embedded maps.

Examples:

iex> map = %{"memberof" => "atoms", "embed" => %{"will" => "convert", "thelist" => "to atoms"}}
iex> Morphix.atomorphiform(map, ["memberof", "thelist"])
{:ok, %{"embed" => %{"will" => "convert", thelist: "to atoms"}, memberof: "atoms"}}
Link to this function

atomorphiform!(map)

Specs

atomorphiform!(map()) :: map()

Takes a map as an argument and returns the same map, with all string keys (including keys in nested maps) converted to atom keys.

Examples:

iex> Morphix.atomorphiform!(%{:this => %{map: %{"has" => "a", :nested => "string", :for =>  %{a: :key}}}, "the" =>  %{"other" => %{map: :does}}, as: "well"})
%{this: %{map: %{has: "a", nested: "string", for: %{a: :key}}}, the: %{other: %{map: :does}}, as: "well"}

iex> Morphix.atomorphiform!(%{"this" => ["map", %{"has" => ["a", "list"]}], "inside" => "it"})
%{this: ["map", %{has: ["a", "list"]}], inside: "it"}
Link to this function

atomorphiform!(map, allowed)

Specs

atomorphiform!(map(), :safe) :: map()
atomorphiform!(map(), list()) :: map()

Takes a map and a list of allowed strings as arguments and returns the same map, with any strings that are in the list converted to atoms, and any strings that are not in the list left as strings.

Works recursively on embedded maps.

Examples:

iex> map = %{"memberof" => "atoms", "embed" => %{"will" => "convert", "thelist" => "to atoms"}}
iex> Morphix.atomorphiform!(map, ["memberof", "thelist"])
%{"embed" => %{"will" => "convert", thelist: "to atoms"}, memberof: "atoms"}
iex> map = %{"id" => "fooobarrr", "date_of_birth" => ~D[2014-04-14]}
%{"date_of_birth" => ~D[2014-04-14], "id" => "fooobarrr"}
iex> Morphix.atomorphiform!(map)
%{id: "fooobarrr", date_of_birth: ~D[2014-04-14]}
Link to this function

atomorphify(map)

Specs

atomorphify(map()) :: {:ok, map()}

Takes a map as an argument and returns {:ok, map}, with string keys converted to atom keys. Does not examine nested maps.

Examples

iex> Morphix.atomorphify(%{"this" => "map", "has" => %{"string" => "keys"}})
{:ok, %{this: "map", has: %{"string" => "keys"}}}

iex> Morphix.atomorphify(%{1 => "2", "1" => 2, "one" => :two})
{:ok, %{1 => "2", "1": 2, one: :two}}
Link to this function

atomorphify(map, allowed)

Specs

atomorphify(map(), :safe) :: {:ok, map()}
atomorphify(map(), list()) :: {:ok, map()}

Takes a map and a list of allowed strings to convert to atoms and returns {:ok, map}, with string keys in the list converted to atoms. Ignores nested maps.

Examples:

iex> Morphix.atomorphify(%{"allowed_key" => "exists", "non_existent_atom" => "does_not", 1 => "is_ignored"}, ["allowed_key"])
{:ok, %{ "non_existent_atom" => "does_not", 1 => "is_ignored", allowed_key: "exists"}}
Link to this function

atomorphify!(map)

Specs

atomorphify!(map()) :: map()

Takes a map as an argument and returns the same map with string keys converted to atom keys. Does not examine nested maps.

Examples

iex> Morphix.atomorphify!(%{"this" => "map", "has" => %{"string" => "keys"}})
%{this: "map", has: %{"string" => "keys"}}

iex> Morphix.atomorphify!(%{1 => "2", "1" => 2, "one" => :two})
%{1 => "2", "1": 2, one: :two}
Link to this function

atomorphify!(map, allowed)

Specs

atomorphify!(map(), :safe) :: map()
atomorphify!(map(), list()) :: map()

Takes a map and a list of allowed strings to convert to atoms and returns the same map, with string keys in the list converted to atoms. Ignores nested maps.

Examples:

iex> Morphix.atomorphify!(%{"allowed_key" => "exists", "non_existent_atom" => "does_not", 1 => "is_ignored"}, ["allowed_key"])
%{"non_existent_atom" => "does_not", 1 => "is_ignored", allowed_key: "exists"}
Link to this function

compactiform(map)

Specs

compactiform(map() | list()) ::
  {:ok, map()}
  | {:ok, list()}
  | {:error, %ArgumentError{__exception__: term(), message: term()}}

Removes keys with nil values from maps and nil elements from lists. It also handles nested maps and lists, and treats empty maps as nil values.

Examples

iex> Morphix.compactiform(%{a: nil, b: "not", c: %{d: nil, e: %{}, f: %{g: "value"}}})
{:ok, %{b: "not", c: %{f: %{g: "value"}}}}

iex> Morphix.compactiform(%{has: %{a: ["list", "with", nil]}, and: ["a", %{nested: "map", with: nil}]})
{:ok, %{has: %{a: ["list", "with"]}, and: ["a", %{nested: "map"}]}}

iex> Morphix.compactiform(["list", %{a: "map", with: nil, and_empty: []}])
{:ok, ["list", %{a: "map", and_empty: []}]}

iex> Morphix.compactiform(5)
{:error, %ArgumentError{message: "expecting a map or a list, got: 5"}}
Link to this function

compactiform!(map)

Specs

compactiform!(map() | list()) ::
  map() | list() | %ArgumentError{__exception__: term(), message: term()}

Removes keys with nil values from nested maps, eliminates empty maps, and removes nil values from nested lists.

Examples

iex> Morphix.compactiform!(%{nil_nil: nil, not_nil: "a value", nested: %{nil_val: nil, other: "other"}})
%{not_nil: "a value", nested: %{other: "other"}}

iex> Morphix.compactiform!(%{nil_nil: nil, not_nil: "a value", nested: %{nil_val: nil, other: "other", nested_empty: %{}}})
%{not_nil: "a value", nested: %{other: "other"}}

iex> Morphix.compactiform!([nil, "string", %{nil_nil: nil, not_nil: "a value", nested: %{nil_val: nil, other: "other", nested_empty: %{}}}, ["nested", nil, 2]])
["string", %{not_nil: "a value", nested: %{other: "other"}}, ["nested", 2]]
Link to this function

compactify(map_or_list)

Specs

compactify(map() | list()) ::
  {:ok, map()}
  | {:ok, list()}
  | {:error, %ArgumentError{__exception__: term(), message: term()}}

Takes a map or a list and removes any keys or elements that have nil values.

Examples

iex> Morphix.compactify(%{nil_key: nil, not_nil: "real value"})
{:ok, %{not_nil: "real value"}}

iex> Morphix.compactify([1, nil, "string", %{key: :value}])
{:ok, [1, "string", %{key: :value}]}

iex> Morphix.compactify([a: nil, b: 2, c: "string"])
{:ok, [b: 2, c: "string"]}

iex> Morphix.compactify(%{empty: %{}, not: "not"})
{:ok, %{not: "not"}}

iex> Morphix.compactify("won't work")
{:error, %ArgumentError{message: "expecting a map or a list, got: \"won't work\""}}
Link to this function

compactify!(map)

Specs

compactify!(map() | list()) ::
  map() | list() | %ArgumentError{__exception__: term(), message: term()}

Takes a map or list and removes keys or elements that have nil values, or are empty maps.

Examples

iex> Morphix.compactify!(%{nil_key: nil, not_nil: "nil"})
%{not_nil: "nil"}

iex> Morphix.compactify!([1, nil, "string", %{key: :value}])
[1, "string", %{key: :value}]

iex> Morphix.compactify!([a: nil, b: 2, c: "string"])
[b: 2, c: "string"]

iex> Morphix.compactify!(%{empty: %{}, not: "not"})
%{not: "not"}

iex> Morphix.compactify!({"not", "a map"})
** (ArgumentError) expecting a map or a list, got: {"not", "a map"}
Link to this function

equaliform?(any1, any2)

Specs

equaliform?(any(), any()) :: boolean()

Takes two elements and returns true if they are equal, ignoring order for Enumerables. Order is also ignored for nested Enumerables.

Examples:

iex> Morphix.equaliform?([1, ["two", :three], %{a: 1, c: "three", e: %{d: 4, b: 2}}], [["two", :three], 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
true

iex> Morphix.equaliform?([1, "two", :three, %{a: 1, c: "three", e: %{g: 4, b: 2}}], ["two", :three, 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
false
Link to this function

equalify?(any1, any2)

Specs

equalify?(any(), any()) :: boolean()

Takes two elements and returns true if they are equal, ignoring order for Enumerables. Order is not ignored for nested Enumerables.

Examples:

iex> Morphix.equalify?([1, ["two", :three], %{a: 1, c: "three", e: %{d: 4, b: 2}}], [["two", :three], 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
true

iex> Morphix.equalify?([1, ["two", :three], %{a: 1, c: "three", e: %{d: 4, b: 2}}], [[:three, "two"], 1, %{c: "three", a: 1, e: %{b: 2, d: 4}}])
false
Link to this function

morphiflat(map)

Specs

morphiflat(map()) :: {:ok | :error, map() | String}

Takes a map and returns a flattened version of that map. If the map has nested maps (or the maps nested maps have nested maps, etc.) morphiflat moves all nested key/value pairs to the top level, discarding the original keys.

Examples:

iex> Morphix.morphiflat %{this: %{nested: :map, inner: %{twonested: :map, is: "now flat"}}}
{:ok, %{nested: :map, twonested: :map, is: "now flat"}}

In the example, the key :this is discarded, along with the key inner, because they both point to map values.

Will return {:error, <input> is not a Map} if the input is not a map.

Examples:

iex> Morphix.morphiflat({1,2,3})
{:error, "{1, 2, 3} is not a Map"}
Link to this function

morphiflat!(map)

Specs

morphiflat!(map()) :: map()

Takes a map and returns a flattend version of that map, discarding any nested keys.

Examples:

iex> Morphix.morphiflat! %{you: "will", youwill: %{be: "discarded"}}
%{you: "will", be: "discarded"}
Link to this function

morphiform!(map, transformer, allowed \\ [])

Specs

morphiform!(map(), (... -> any()), list()) :: map()

Takes a map and a function as an argument and returns the same map, with all keys transformed by the function.(including keys in nested maps) converted to atom keys.

The function passed in must take two arguments, the key, and an allowed list.

Examples:

iex> Morphix.morphiform!(%{"this" => %{"map" => %{"has" => "a", "nested" => "string", "for" =>  %{"a" => :key}}}, "the" =>  %{"other" => %{"map" => :does}},"as" => "well"}, fn key, [] -> String.upcase(key) end)
%{"THIS" => %{"MAP" => %{"HAS" => "a", "NESTED" => "string", "FOR" => %{"A" => :key}}}, "THE" => %{"OTHER" => %{"MAP" => :does}}, "AS" => "well"}
Link to this function

morphify(enum, funct)

Specs

morphify([any()], (... -> any())) :: {:ok | :error, map() | String.t()}
morphify(tuple(), (... -> any())) :: {:ok | :error, map() | String.t()}

Takes a List and a function as arguments and returns {:ok, Map}, with the keys of the map the result of applying the function to each item in the list.

If the function cannot be applied, will return {:error, message}

Examples

iex> Morphix.morphify([[1,2,3], [12], [1,2,3,4]], &Enum.count/1)
{:ok, %{1 => [12], 3 => [1,2,3], 4 => [1,2,3,4]}}

iex> Morphix.morphify({[1,2,3], [12], [1,2,3,4]}, &length/1)
{:ok, %{1 => [12], 3 => [1,2,3], 4 => [1,2,3,4]}}

iex> Morphix.morphify([1,2], &String.length/1)
{:error, "Unable to apply &String.length/1 to each of [1, 2]"}
Link to this function

morphify!(enum, funct)

Specs

morphify!([any()], (... -> any())) :: map()
morphify!(tuple(), (... -> any())) :: map()

Takes a list and a function as arguments and returns a Map, with the keys of the map the result of applying the function to each item in the list.

Examples

iex> Morphix.morphify!([[1,2,3], [12], [1,2,3,4]], &Enum.count/1)
%{1 => [12], 3 => [1,2,3], 4 => [1,2,3,4]}
Link to this function

partiphify(list, k)

Specs

partiphify(list(), integer()) :: {:ok, [list()[any()]]} | {:error, term()}

Divides a list into k distinct sub-lists, with partitions being as close to the same size as possible

Examples

iex> Morphix.partiphify([1,2,3,4,5,6], 4)
{:ok, [[3], [4], [5, 1], [6, 2]]}

iex> Morphix.partiphify(("abcdefghijklmnop" |> String.split("", trim: true)), 4)
{:ok, [["a", "b", "c", "d"], ["e", "f", "g", "h"], ["i", "j", "k", "l"], ["m", "n", "o", "p"]]}
Link to this function

partiphify!(list, k)

Specs

partiphify!(list(), integer()) :: [list()[any()]] | no_return()

Divides a list into k distinct sub-lists, with partitions being as close to the same size as possible

Examples

iex> Morphix.partiphify!([1,2,3,4,5,6], 4)
[[3], [4], [5, 1], [6, 2]]

iex> Morphix.partiphify!(("abcdefghijklmnop" |> String.split("", trim: true)), 4)
[["a", "b", "c", "d"], ["e", "f", "g", "h"], ["i", "j", "k", "l"], ["m", "n", "o", "p"]]
Link to this function

stringmorphiform!(map)

Specs

stringmorphiform!(map()) :: map()
Link to this function

stringmorphiform!(map, allowed)

Specs

stringmorphiform!(map(), list()) :: map()
Link to this function

stringmorphify!(map)

Specs

stringmorphify!(map()) :: map()

Takes a map as an argument and returns the same map with atom keys converted to string keys. Does not examine nested maps.

Examples

iex> Morphix.stringmorphify!(%{this: "map", has: %{"string" => "keys"} })
%{"this" => "map", "has" => %{"string" => "keys"}}

iex> Morphix.stringmorphify!(%{1 => "2", "1" => 2, one: :two})
%{1 => "2", "1" => 2, "one" => :two}
Link to this function

stringmorphify!(map, allowed)

Specs

stringmorphify!(map(), list()) :: map()

Takes a map and a list of allowed atoms as arguments and returns the same map, with any atoms that are in the list converted to strings, and any atoms that are not in the list left as atoms.

Examples:

iex> map = %{memberof: "atoms", embeded: %{"wont" => "convert"}}
iex> Morphix.stringmorphify!(map, [:memberof])
%{:embeded => %{"wont" => "convert"}, "memberof" => "atoms"}
iex> map = %{id: "fooobarrr", date_of_birth: ~D[2014-04-14]}
iex> Morphix.stringmorphify!(map)
%{"id" => "fooobarrr", "date_of_birth" => ~D[2014-04-14]}