#Goal
キーワードリストのkeyによって処理を変える一例。
#Dev-Environment
OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
#Body
ブログからの転載です。
キーワードリストを再帰で処理して、keyによってマッチする関数が変わるものを作成します。
たまには頭を使わないといけませんね。(この程度とか言わないで・・・)
Example:
defmodule ArgumentsSample do
@spec sample(Keyword.t) :: any
def sample(kw) do
keys = Keyword.keys(kw)
values = Keyword.values(kw)
IO.puts "Start..."
sample(keys, values)
end
@match1 [:hoge, :huge]
@match2 [:foo, :bar]
defp sample([key|keys_tail], [value|values_tail]) when key in @match1 do
IO.puts "@match1 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample([key|keys_tail], [value|values_tail]) when key in @match2 do
IO.puts "@match2 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample(key, value) do
IO.puts "...End"
end
end
Note:
キーワードリストのkey / value部分のみを抽出するには...
iex> Keyword.keys([hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5])
[:hoge, :foo, :bar, :hoge, :huge]
iex> Keyword.values([hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5])
[1, 2, 3, 4, 5]
Caution:
:hoge、:huge、:foo、:barにマッチしない場合の処理は書いていません。
現在のままだとマッチしないキーが来たら、そこで処理が終わります。
さて、実行してみましょう。
Result:
iex> ArgumentsSample.sample hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5
Start...
@match1 match
hoge = 1
@match2 match
foo = 2
@match2 match
bar = 3
@match1 match
hoge = 4
@match1 match
huge = 5
...End
:ok
順番に実行の流れを見てみましょう。
1:
# sample(kw)を実行
sample([hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5])
# keysとvaluesの内容
keys: [:hoge, :foo, :bar, :hoge, :huge]
values: [1, 2, 3, 4, 5]
# マッチさせる内容
@match1 [:hoge, :huge]
@match2 [:foo, :bar]
2:
# when key in @match1にマッチ
sample([:hoge|[:foo, :bar, :hoge, :huge]], [1|[2, 3, 4, 5]])
3:
# when key in @match2にマッチ
sample([:foo|[:bar, :hoge, :huge]], [2|[3, 4, 5]])
4:
# when key in @match2にマッチ
sample([:bar|[:hoge, :huge]], [3|[4, 5]])
5:
# when key in @match1にマッチ
sample([:hoge|[:huge]], [4|[5]])
6:
# when key in @match1にマッチ
sample([:huge|[]], [5|[]])
7:
# sample(key, value)にマッチ
sample([], [])
こうすれば、キーによって処理を変えることができる。
Ectoでfromを処理する時にやっていると聞いたので、気になって作ってみた。
#Bibliography
hexdocs - v1.0.5 Elixir Kernel.Typespec
elixir-lang - Typespecs and behaviours
hexdocs - v1.0.5 Elixir Keyword
Github - v0.16.0 Ecto(query.ex#L241)