Today’s Erlang Thursday is lists:zip/2.
lists:zip/2
returns a new list of two-tuples, from the corresponding elements of the two lists passed as arguments.
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>}]
If the lists are not of the same length a function clause match exception is thrown.
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)
There is also a 3-arity version of the zip function lists:zip3/3, which behaves like lists:zip/2
but takes three lists as arguments instead of two.
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"}]
If you need to combine the arguments in a different manner, you can use lists:zipwith/3, or lists:zipwith3/4, each of which takes as the first argument a 2-arity combining function.
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"}]
–Proctor