defmodule Panty.Collection do @moduledoc """ Collection utilities """ @doc """ Get index of a substring from a pattern. ## Examples iex> Collection.string_find_index("abcdef", "cde") 2 iex> Collection.string_find_index("{% sections 'header' %}", "{% endschema %}") nil """ @spec substring_index(String.t, String.t) :: integer() | nil def substring_index(pattern, substring) do case String.split(pattern, substring, parts: 2) do [left, _] -> String.length(left) [_] -> nil end end @doc """ Get intersection from given lists. ## Examples iex> Collection.intersection([1, 2, 3, 4], [2, 3]) [2, 3] iex> Collection.intersection(["index", "carousel", "header", "footer"], ["header", "footer"]) ["header", "footer"] """ @spec intersection([any()], [any()]) :: [any()] def intersection(first, second) do first |> Enum.filter(&(Enum.member?(second, &1))) end @doc """ Returns the list dropping its last element ## Examples iex> Collection.initial([1, 2, 3, 4]) [1, 2, 3] """ @spec initial([any(), ...]) :: [any()] def initial(collection), do: _initial(collection) def _initial([_]), do: [] def _initial([h|t]), do: [h| _initial(t)] @doc """ Remove all falsy values in collection ## Examples iex> Collection.compact([1, 2, 3, nil, 4, nil, 5]) [1, 2, 3, 4, 5] iex> Collection.compact(["hello", "hola", false, "bonjour"]) ["hello", "hola", "bonjour"] """ @spec compact([any()]) :: [any()] def compact(collection) do Enum.reject(collection, fn nil -> true false -> true _ -> false end) end @doc """ Remove all elements that match the pattern in a collection ## Examples iex> Collection.reject([1, 2, 3, nil, 4, nil, 5], nil) [1, 2, 3, 4, 5] iex> Collection.reject(["morning", "afternoon", %{a: "noon"}, "night"], %{a: "noon"}) ["morning", "afternoon", "night"] """ @spec reject([any()], any()) :: [any()] def reject(collection, pattern) do Enum.reject(collection, fn el -> el == pattern end) end end