45 lines
1.1 KiB
Elixir
45 lines
1.1 KiB
Elixir
defmodule School do
|
|
@moduledoc """
|
|
Simulate students in a school.
|
|
|
|
Each student is in a grade.
|
|
"""
|
|
|
|
@type school :: any()
|
|
|
|
@doc """
|
|
Create a new, empty school.
|
|
"""
|
|
@spec new() :: school
|
|
def new(), do: %{}
|
|
|
|
@doc """
|
|
Add a student to a particular grade in school.
|
|
"""
|
|
@spec add(school, String.t(), integer) :: {:ok | :error, school}
|
|
def add(school, name, grade) do
|
|
if Enum.any?(roster(school), &(&1 == name)) do
|
|
{:error, school}
|
|
else
|
|
{:ok, Map.put(school, grade, [name | Map.get(school, grade, [])])}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Return the names of the students in a particular grade, sorted alphabetically.
|
|
"""
|
|
@spec grade(school, integer) :: [String.t()]
|
|
def grade(school, grade) when not is_map_key(school, grade), do: []
|
|
def grade(school, grade), do: Enum.sort(Map.get(school, grade))
|
|
|
|
@doc """
|
|
Return the names of all the students in the school sorted by grade and name.
|
|
"""
|
|
@spec roster(school) :: [String.t()]
|
|
def roster(school) do
|
|
for grade <- Enum.sort(Map.keys(school)), reduce: [] do
|
|
acc -> acc ++ grade(school, grade)
|
|
end
|
|
end
|
|
end
|