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"]]
上の例は、各リストの要素から新しくリストを作成した例。