次の関数を、ライブラリやリスト内包表記を利用せずに実装しろ、と。
- all?
- each
- filter
- split
- take
defmodule MyList do def all?([]), do: true def all?([head | tail]) when head, do: all?(tail) def all?(_list), do: false def each([], _func) do end def each([head|tail], func) do func.(head) each(tail, func) end def filter([], _prod) do [] end def filter([head|tail], prod) do if prod.(head) do [head | filter(tail, prod)] else filter(tail, prod) end end def split(list, n), do: _split({[], list}, n) defp _split(result, 0), do: result defp _split(result = {_left, []}, _), do: result defp _split({left, [head|tail]}, n), do: _split({left ++ [head], tail}, n - 1) def take(list, n) do {result, _} = split(list, n) result end end
順番に行ってみよう。まずは all?
。
^o^ > iex practice_10_1.exs Eshell V8.0 (abort with ^G) Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> MyList.all?([true, true, true]) true iex(2)> MyList.all?([true, false, true]) false
つぎに each
。
iex(3)> MyList.each([1, 2, 3], &IO.puts/1) 1 2 3 nil
nil
は each
自体の返り値かな。
つぎ、filter
。
iex(4)> MyList.filter([1, 2, 3, 4, 5], &(&1 > 2)) [3, 4, 5]
split
。
iex(5)> MyList.split([1, 2, 3, 4, 5], 2) {[1, 2], [3, 4, 5]}
最後に take
。
iex(6)> MyList.take([1, 2, 3, 4, 5], 3) [1, 2, 3]