-
Notifications
You must be signed in to change notification settings - Fork 2
/
mode.ex
49 lines (39 loc) · 1.14 KB
/
mode.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
defmodule Statistex.Mode do
@moduledoc false
import Statistex
@spec mode(Statistex.samples(), keyword) :: Statistex.mode()
def mode([], _) do
raise(
ArgumentError,
"Passed an empty list ([]) to calculate statistics from, please pass a list containing at least one number."
)
end
def mode(samples, opts) do
frequencies =
Keyword.get_lazy(opts, :frequency_distribution, fn -> frequency_distribution(samples) end)
frequencies
|> max_multiple()
|> decide_mode()
end
defp max_multiple(map) do
max_multiple(Enum.to_list(map), [{nil, 0}])
end
defp max_multiple([{sample, count} | rest], ref = [{_, max_count} | _]) do
new_ref =
cond do
count < max_count -> ref
count == max_count -> [{sample, count} | ref]
true -> [{sample, count}]
end
max_multiple(rest, new_ref)
end
defp max_multiple([], ref) do
ref
end
defp decide_mode([{nil, _}]), do: nil
defp decide_mode([{_, 1} | _rest]), do: nil
defp decide_mode([{sample, _count}]), do: sample
defp decide_mode(multi_modes) do
Enum.map(multi_modes, fn {sample, _} -> sample end)
end
end