Erlang Thursday - lists:zip/2

今天的Erlang Thursday讲的函数是 lists:zip/2.

lists:zip/2 返回一个由两元素元组组成的列表,其中两元素元组是由两个入参列表位置相对应的元素组成。

1
2
3
4
5
6
lists:zip([a, b, c, d], [1, 2, 3, 4]).
% [{a,1},{b,2},{c,3},{d,4}]
lists:zip([a, b, c, d], [{1, 3}, {2, 5}, {3, 7}, {4, 11}]).
% [{a,{1,3}},{b,{2,5}},{c,{3,7}},{d,{4,11}}]
lists:zip([a, b], [fun lists:map/3, fun lists:foldl/3]).
% [{a,#Fun<lists.map.3>},{b,#Fun<lists.foldl.3>}]

如果两个入参列表的长度不同,将抛出一个函数子句不匹配(function clause match)的异常。

1
2
3
4
5
6
7
8
lists:zip([a, b, c, d], [1, 2, 3]).
% ** exception error: no function clause matching lists:zip([d],[]) (lists.erl, line 385)
% in function lists:zip/2 (lists.erl, line 385)
% in call from lists:zip/2 (lists.erl, line 385)
lists:zip([a, b, c], [1, 2, 3, 4]).
% ** exception error: no function clause matching lists:zip([],[4]) (lists.erl, line 385)
% in function lists:zip/2 (lists.erl, line 385)
% in call from lists:zip/2 (lists.erl, line 385)

也有接收3个入参版本的zip函数:lists:zip3/3,它的功能和 lists:zip/2 一样,只是入参为3个列表而不是2个列表。

1
2
lists:zip3([a, b, c, d], [1, 2, 3, 4], ["alpha", "bravo", "charlie", "delta"]).
% [{a,1,"alpha"},{b,2,"bravo"},{c,3,"charlie"},{d,4,"delta"}]

如果你想用不同的方式来组合列表中的元素,你可以用 lists:zipwith/3 或者 lists:zipwith3/4,它们的第一个入参是一个接收两个入参的组合函数。

1
2
3
4
5
6
7
8
9
10
11
lists:zipwith(fun(X, Y) -> X * Y end, [1, 2, 3, 4], [2, 3, 4, 5]).
% [2,6,12,20]
lists:zipwith(fun(X, Y) -> X + Y end, [1, 2, 3, 4], [2, 3, 4, 5]).
% [3,5,7,9]
lists:zipwith3(fun(X, Y, Z) -> X * Y * Z end, [1, 2, 3, 4], [2, 3, 4, 5], [4, 3, 2, 1]).
% [8,18,24,20]
lists:zipwith3(fun(X, Y, Z) -> {{X, Y}, Z} end, [a, b, c, d], [1, 2, 3, 4], ["alpha", "bravo", "charlie", "delta"]).
% [{{a,1},"alpha"},
% {{b,2},"bravo"},
% {{c,3},"charlie"},
% {{d,4},"delta"}]

原文链接: https://www.proctor-it.com/erlang-thursday-lists-zip-2/