Current section
Files
Jump to
Current section
Files
lib/minmaxlist.ex
defmodule Minmaxlist do
@doc """
Returns list of entries that gives the minimum value as calculated by the given function.
iex> [1, 2, 3, 4, 5, 6] |> Minmaxlist.min_list_by(&(rem(&1,3)))
[3, 6]
iex> [] |> Minmaxlist.min_list_by(&(rem(&1,3)))
[]
"""
def min_list_by(collection, fun) do
result = collection |> Enum.reduce(:first, fn
entry, :first ->
fun_entry = fun.(entry)
{[entry], fun_entry}
entry, {acc_entries, acc_fun_entry} ->
fun_entry = fun.(entry)
cond do
fun_entry == acc_fun_entry -> {[entry|acc_entries], fun_entry}
fun_entry < acc_fun_entry -> {[entry], fun_entry}
true -> {acc_entries, acc_fun_entry}
end
end)
case result do
:first -> []
_ -> result |> elem(0) |> Enum.reverse
end
end
@doc """
Returns list of entries that gives the maximum value as calculated by the given function.
iex> [1, 2, 3, 4, 5, 6] |> Minmaxlist.max_list_by(&(rem(&1,3)))
[2, 5]
iex> [] |> Minmaxlist.max_list_by(&(rem(&1,3)))
[]
"""
def max_list_by(collection, fun) do
result = collection |> Enum.reduce(:first, fn
entry, :first ->
fun_entry = fun.(entry)
{[entry], fun_entry}
entry, {acc_entries, acc_fun_entry} ->
fun_entry = fun.(entry)
cond do
fun_entry == acc_fun_entry -> {[entry|acc_entries], fun_entry}
fun_entry > acc_fun_entry -> {[entry], fun_entry}
true -> {acc_entries, acc_fun_entry}
end
end)
case result do
:first -> []
_ -> result |> elem(0) |> Enum.reverse
end
end
@doc """
Returns list of entries that gives the minimum & maximum value as calculated by the given function.
iex> [1, 2, 3, 4, 5, 6] |> Minmaxlist.min_max_list_by(&(rem(&1,3)))
{[3, 6], [2, 5]}
iex> [] |> Minmaxlist.min_max_list_by(&(rem(&1,3)))
{[], []}
"""
def min_max_list_by(collection, fun) do
result = collection |> Enum.reduce(:first, fn
entry, :first ->
fun_entry = fun.(entry)
{{[entry], fun_entry}, {[entry], fun_entry}}
entry, {acc_min={acc_min_entries, acc_min_fun_entry}, acc_max={acc_max_entries, acc_max_fun_entry}} ->
fun_entry = fun.(entry)
acc_min = cond do
fun_entry == acc_min_fun_entry -> {[entry|acc_min_entries], fun_entry}
fun_entry < acc_min_fun_entry -> {[entry], fun_entry}
true -> acc_min
end
acc_max = cond do
fun_entry == acc_max_fun_entry -> {[entry|acc_max_entries], fun_entry}
fun_entry > acc_max_fun_entry -> {[entry], fun_entry}
true -> acc_max
end
{acc_min, acc_max}
end)
case result do
:first -> {[], []}
{result_min, result_max} -> {result_min |> elem(0) |> Enum.reverse, result_max |> elem(0) |> Enum.reverse}
end
end
end