無題の備忘録

IT技術について調べたことや学んだこと、試したこと記録するブログです。Erlang、ネットワーク、 セキュリティ、Linux関係のものが多いです。

Erlang の lists モジュールを一通り試す - その7

最近、Erlang のコードを読んでいて、lists:any という関数が出てきたのだが、知らなかったので調べた。ついでに、他の関数も一通り眺めておく。

公式URL: http://erlang.org/doc/man/lists.html

ukeymerge/3 関数

ukeymerge(N, TupleList1, TupleList2) -> TupleList3

Types

N = integer() >= 1
1..tuple_size(Tuple)
TupleList1 = [T1]
TupleList2 = [T2]
TupleList3 = [T1 | T2]
T1 = T2 = Tuple
Tuple = tuple()

TupleList1 と TupleList2 をマージしてソートしたリストを返す。 マージは、各タプルの N 番目の要素で実行される。 この関数を評価する前に、TupleList1 と TupleList2 の両方を重複なくキーでソートする必要がある。 2つのタプルが等しい場合、TupleList1 のタプルが選択され、TupleList2 のタプルが削除される。

> TupleList1 = [{apple,130},{cherry,160}].
> TupleList2 = [{apple,120},{banana,130},{strawberry,140}].
[{apple,120},{banana,130},{strawberry,140}]
> lists:ukeymerge(1, TupleList1, TupleList2).
[{apple,130},{banana,130},{cherry,160},{strawberry,140}]

似た関数に keymerge/3 があるが、この関数と異なる点は、ukeymerge/3 は重複するキーのタプルは削除される点だ。

ukeysort/2 関数

ukeysort(N, TupleList1) -> TupleList2

Types

N = integer() >= 1
1..tuple_size(Tuple)
TupleList1 = TupleList2 = [Tuple]
Tuple = tuple()

タプルの N 番目の要素でソートされたリストを返す。N 番目の要素が同じものは最初の要素以外が削除される。

> lists:ukeysort(1, [{apple,130},{cherry,160},{apple,120},{banana,130},{strawberry,140}]).             
[{apple,130},{banana,130},{cherry,160},{strawberry,140}]

上記の例は、指定した1番目の要素で、apple のタプルが重複しているが、2つ目のappleが削除されている。

umerge/1 関数

umerge(ListOfLists) -> List1

Types

ListOfLists = [List]
List = List1 = [T]
T = term()

ListOfLists のすべてのサブリストをマージしてソートしたリストを返す。 この関数を評価する前に、すべてのサブリストをソートし、重複を含んでいない状態にする。 2つの要素が等しい場合、ListOfListsで最も低い位置にあるサブリストの要素が選択され、もう一方は削除される。

> SubList1 = [a, b, c, d, e].
> SubList2 = [1, 2, a, b, c].
> SubList3 = [1, 2, 3, 4, 5].
> lists:umerge([SubList1, SubList2, SubList3]).
[1,2,3,4,5,a,b,c,d,e]

SubList2 をわざとソートできていない状態で、umerge/1 を実行すると、ソートが不完全な戻り値が得られる。必ず引数に与えるサブリストはソートする。

> SubList1 = [a, b, c, d, e].
> SubList2 = [a, b, c, 1, 2].
> SubList3 = [1, 2, 3, 4, 5].
> lists:umerge([SubList1, SubList2, SubList3]).
[1,2,3,4,5,a,b,c,1,2,d,e]

同様に、SubList2 をわざと重複がある状態で、umerge/1 を実行すると、重複の削除が不完全な戻り値が得られる。必ず引数に与えるサブリストの要素を重複がない状態にする。

> SubList1 = [a, b, c, d, e].                  
[a,b,c,d,e]
> SubList2 = [a, b, c, a, b].                  
[a,b,c,a,b]
> SubList3 = [1, 2, 3, 4, 5].                  
[1,2,3,4,5]
> lists:umerge([SubList1, SubList2, SubList3]).
[1,2,3,4,5,a,b,c,a,b,d,e]

umerge/2 関数

umerge(List1, List2) -> List3

Types

List1 = [X]
List2 = [Y]
List3 = [X | Y]
X = Y = term()

List1とList2をマージしてソートしたリストを返す。 この関数を評価する前に、List1とList2の両方をソートし、重複を含んでいない状態にする。 2つの要素が等しい場合、List1の要素が選択され、List2の要素が削除される。

> SubList1 = [a, b, c, d, e].
> SubList2 = [1, 2, a, b, c].
> lists:umerge(SubList1, SubList2).
[1,2,a,b,c,d,e]

umerge/3 関数

umerge(Fun, List1, List2) -> List3

Types

Fun = fun((A, B) -> boolean())
List1 = [A]
List2 = [B]
List3 = [A | B]
A = B = term()

List1とList2をマージしてソートしたリストを返す。 List1とList2の両方は、この関数を評価する前に、順序付け関数 Fun に従ってソートされ、重複を含まない必要がある。 Fun(A,B) は、Aが順序でB以下である場合は true を返し、そうでない場合は false を返す。 2つの要素が等しい場合、List1の要素が選択され、List2の要素が削除される。

> F = fun(A, B) -> A >= B end.
#Fun<erl_eval.12.99386804>
> SubList1 = [f,d,c,a].
> SubList2 = [g,f,e,b].
>  lists:umerge(F, SubList1, SubList2).
[g,f,e,d,c,b,a]

Fun が true を返す場合、AがB以下ではないので、A=B を含めるが、 false を返す場合は AがBより順序で大きいので、A=Bを含めない。Fun を下記のように=をなしで指定すると、重複が削除されないので注意する。

> F = fun(A, B) -> A > B end. 
#Fun<erl_eval.12.99386804>
> SubList1 = [f,d,c,a].
> SubList2 = [g,f,e,b].
> lists:umerge(F, SubList1, SubList2). 
[g,f,f,e,d,c,b,a]

umerge3/3 関数

umerge3(List1, List2, List3) -> List4

Types

List1 = [X]
List2 = [Y]
List3 = [Z]
List4 = [X | Y | Z]
X = Y = Z = term()

List1、List2、およびList3をマージしてソートしたリストを返す。 この関数を評価する前に、List1、List2、およびList3をすべて並べ替え、重複を含んでいない状態にする。 2つの要素が等しい場合、そのような要素があれば List1 の要素が選択され、そうでない場合は List2 の要素が選択され、List3 の要素が削除される。

> SubList1 = [a, b, c, d, e].
> SubList2 = [1, 2, a, b, c].
> SubList3 = [1, 2, 3, 4, 5].
> lists:umerge3(SubList1, SubList2, SubList3).
[1,2,3,4,5,a,b,c,d,e]

unzip/1 関数

unzip(List1) -> {List2, List3}

Types

List1 = [{A, B}]
List2 = [A]
List3 = [B]
A = B = term()

2つのタプルのリストを2つのリストに「解凍」する。最初のリストには各タプルの最初の要素が含まれ、2番目のリストには各タプルの2番目の要素が含まれる。

> List1 = [{a, "A"},{b, "B"},{c, "C"}].
> lists:unzip(List1).
{[a,b,c],["A","B","C"]}

この関数の引数のリストに含まれるタプルは、2つ要素で構成されたタプルである必要がある。そうでない場合は、no function clause matching でクラッシュする。

> List1 = [{a, "A1", "A2"},{b, "B1", "B2"},{c, "C1", "C2"}].
> lists:unzip(List1).
** exception error: no function clause matching lists:unzip([{a,"A1","A2"},{b,"B1","B2"},{c,"C1","C2"}],[],[]) (lists.erl, line 402)

unzip3/1 関数

unzip3(List1) -> {List2, List3, List4}

Types

List1 = [{A, B, C}]
List2 = [A]
List3 = [B]
List4 = [C]
A = B = C = term()

3つのタプルのリストを3つのリストに「解凍」する。最初のリストには各タプルの最初の要素が含まれ、2番目のリストには各タプルの2番目の要素が含まれ、3番目のリストには各タプルの3番目の要素が含まれる。

> List1 = [{a, "A1", "A2"},{b, "B1", "B2"},{c, "C1", "C2"}].
> lists:unzip3(List1).
{[a,b,c],["A1","B1","C1"],["A2","B2","C2"]}

usort/1 関数

usort(List1) -> List2

Types

List1 = List2 = [T]
T = term()

List1 の要素のうち、最初の1つの残して等しい要素が削除され、ソートされたリストを返す。

> lists:usort([a,b,c,a,d,e,f,a,b,e]).
[a,b,c,d,e,f]
> lists:usort([{apple,130},{cherry,160},{apple,130},{banana,130},{strawberry,140}]).
[{apple,130},{banana,130},{cherry,160},{strawberry,140}]

usort/2 関数

usort(Fun, List1) -> List2

Types

Fun = fun((T, T) -> boolean())
List1 = List2 = [T]
T = term()

List1 の要素のうち、順序付け関数 Fun に従って、最初の1つの残して等しい要素が削除され、ソートされたリストを返す。 Fun(A,B)は、Aが順序でB以下である場合は true を返し、そうでない場合はfalseを返す。

>  F = fun(A, B) -> A >= B end.
#Fun<erl_eval.13.126501267>
> lists:usort(F, [a,b,c,a,d,e,f,a,b,e]).
[f,e,d,c,b,a]

zip/2 関数

zip(List1, List2) -> List3

Types

List1 = [A]
List2 = [B]
List3 = [{A, B}]
A = B = term()

長さの等しい2つのリストを、2要素のタプルの1つのリストに「圧縮」する。各タプルの最初の要素は最初のリストから取得され、2番目の要素は2番目のリストから取得される。

> List1 = [a,b,c].
> List2 = ["A","B","C"].
> lists:zip(List1, List2).
[{a,"A"},{b,"B"},{c,"C"}]

もし、リストの長さが異なる場合、no function clause matching でクラッシュする。

> List1 = [a,b,c,d].
> List2 = ["A","B","C"].
> lists:zip(List1, List2).
** exception error: no function clause matching lists:zip([d],[]) (lists.erl, line 387)
     in function  lists:zip/2 (lists.erl, line 387)
     in call from lists:zip/2 (lists.erl, line 387)

zip3/3 関数

zip3(List1, List2, List3) -> List4

Types

List1 = [A]
List2 = [B]
List3 = [C]
List4 = [{A, B, C}]
A = B = C = term()

等しい長さの3つのリストを3要素のタプルの1つのリストに「圧縮」する。各タプルの最初の要素は最初のリストから取得され、2番目の要素は2番目のリストから取得され、3番目の要素は3番目のリストの対応する要素から取得される。

> List1 = [a,b,c].
> List2 = ["A1","B1","C1"].
> List3 = ["A2","B2","C2"].
> lists:zip3(List1, List2, List3).
[{a,"A1","A2"},{b,"B1","B2"},{c,"C1","C2"}]

zipwith/3 関数

zipwith(Combine, List1, List2) -> List3

Types

Combine = fun((X, Y) -> T)
List1 = [X]
List2 = [Y]
List3 = [T]
X = Y = T = term()

長さが等しい2つのリストの要素を1つのリストに結合する。 2つのリストから要素の各ペアX、Yを取得し、List3 の要素は Combine(X,Y) の戻り値が使われる。

> Combine = fun(X, Y) -> #{X=>Y} end.
#Fun<erl_eval.13.126501267>
> List1 = [a,b,c].
> List2 = ["A","B","C"].
> lists:zipwith(Combine, List1, List2).
[#{a => "A"},#{b => "B"},#{c => "C"}]

上記の例では、zipすると List1 の要素を キー、 List2 の要素を Value とした map() を作成するようにした例。

zipwith3/4 関数

zipwith3(Combine, List1, List2, List3) -> List4

Types

Combine = fun((X, Y, Z) -> T)
List1 = [X]
List2 = [Y]
List3 = [Z]
List4 = [T]
X = Y = Z = T = term()

長さが等しい3つのリストの要素を1つのリストに結合する。 3つのリストからの要素を各グループ X、Y、Z を取得し、List4 の要素は Combine(X,Y, Z) の戻り値が使われる。

> Combine = fun(X, Y, Z) -> [X,Y,Z] end.
#Fun<erl_eval.19.126501267>
> List1 = [a,b,c].
> List2 = ["A1","B1","C1"].
> List3 = ["A2","B2","C2"].
> lists:zipwith3(Combine, List1, List2, List3).
[[a,"A1","A2"],[b,"B1","B2"],[c,"C1","C2"]]

上の例は、各リストの要素から新しくリストを作成した例。