soy-curd's blog

へぼプログラマーです [https://twitter.com/soycurd1]

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とかを使わなきゃいけないことも組み込みで入っていて便利。

Erlang -- lists