Erlangでリスト操作(map, filter, foldl等)
今、時間があるときにErlangを触っているのだけれど、関数型デザインの言語だけあってリスト操作の関数が充実している。そこで、Erlangのリスト操作関数の内、よく使いそうなものを以下にリストアップしてみた。
map
リストの各値に関数を適用した新しいリストを返す。
map_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], AddOne = fun(X) -> X + 1 end, lists:map(AddOne, L1).
filter
リストの各値をフィルターしたリストを返す。
filter_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsEven = fun(X) -> X rem 2 == 0 end, lists:filter(IsEven, L1).
fold
リストの各値を畳み込んだ値を返す。リストの左から計算するか右から計算するかによってfoldlとfoldrがある。
fold_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], Add = fun(Acc, X) -> Acc + X end, lists:foldl(Add, 0, L1).
zip
2つのリストを合体させる。下の例だと[{1, 11}, {2, 12}, ...]のようなタプルが入ったリストになる。
zip_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], L2 = lists:map(fun(X) -> X + 10 end, L1), lists:zip(L1, L2).
flatten
ネストされたリストからネストのないリストを作る。
flatten_test() -> L1 = [1, 2, 3, [4, 5, 6], 7, 8, 9, 10], lists:flatten(L1).
flatmap
値からリストを作る関数を受け取り、それを引数のリストの値に対して適用してから、flattenする。下の例だと[1,1,1,2,2,2,...]のように返る。
flatmap_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lists:flatmap(fun(X) -> [X, X, X] end, L1).
takewhile, drop while
takewhileは比較関数がtrueまでの値の入ったリストを返す。drop whileはその逆。
takewhile_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:takewhile(IsLess5, L1).
dropwhile_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:dropwhile(IsLess5, L1).
partition
比較関数でリストを分割する。
partition_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], IsLess5 = fun(X) -> X < 5 end, lists:partition(IsLess5, L1).
merge
二つのリストをソートして合体させる。merge/3はソートに用いる比較関数を引数に取れる。
merge_test() -> L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], L2 = lists:map(fun(X) -> X + 10 end, L1), lists:merge(L1, L2).
JSだとunderscoreとかを使わなきゃいけないことも組み込みで入っていて便利。