Erlang Thursday - lists:map/2

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

lists:map/2 接收两个入参,一个是接收一个入参的函数,我们称它为“mapping”函数,另一个是一个Erlang term组成的列表。lists:map/2 的结果是一个列表,这个列表是由入参的列表的每个元素应用于“mapping”函数得到结果组成的。

1
2
3
4
lists:map(fun(X) -> X + 1 end, [1, 2, 3, 4]).
% [2,3,4,5]
lists:map(fun(X) -> X * X end, [1, 2, 3, 4]).
% [1,4,9,16]

因为字符串在Erlang里就是整数列表,所以你也可以将map函数应用在字符串上。

1
2
lists:map(fun(X) -> X - 1 end, "IBM").
% "HAL"

Erlang里的函数

如果你仔细观察上面第一个例子,你会发现第一个入参我们传递的是一个 fun(X) -> X + 1 end. 这是Erlang的匿名函数的语法。 一个匿名函数的格式如下:

1
2
3
4
5
6
7
fun(Args1) OptionalGuardClause1 ->
Expression1, Expression2;
(Args2) OptionalGuardClause2 ->
Expression3, Expression4;
(Args3) OptionalGuardClause3 ->
Expression5, Expression6;
end

因为我们可以像普通函数一样使用匿名函数,除了在17.0以前的版本不能递归调用一个匿名函数外,所以我们可以将一个有多个子句的匿名函数传给lists:map/2 函数。

1
2
lists:map(fun(X) when is_atom(X) -> atom; (X) -> nil end, [1, x, {x}, [], 'B']).
[nil,atom,nil,nil,atom]

传递命名函数给lists:map/2

虽然一些场合我们用匿名函数,但是更多时候为了清晰明了,我们还是想用命名函数。我们可以通过函数的限定名称方式来传递一个命名函数给lists:map/2,采用的格式是,在module:function_name/arity 前面加上 fun 。下面的例子用math:log10/1和erlang:is_atom/1两个函数来演示:

1
2
3
4
lists:map(fun math:log10/1, [1, 10, 100, 1000, 10000]).
[0.0,1.0,2.0,3.0,4.0]
lists:map(fun erlang:is_atom/1, [1, x, {x}, [], 'B']).
[false,true,false,false,true]

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