• 常用列表处理函数
    • member
    • append
    • reverse
    • delete_all

    常用列表处理函数

    以下各小节给出了一些简单列表处理函数的使用示例。这里所描述的所有函数都包含在标准Erlang发行版的lists模块中(细节参见附录C)。

    member

    member(X,L)X是列表L的元素时返回true,否则返回false

    1. member(X, [X|_]) -> true;
    2. member(X, [_|T]) -> member(X, T);
    3. member(X, []) -> false.

    member的第一个子句匹配的是X为列表的第一个元素的情况,这种情况下member返回true。如果第一个子句不匹配,则第二个子句将匹配第二个参数是非空列表的情况,这种情况下模式[_|T]匹配一个非空列表并将T绑定到列表的尾部,然后以原来的X及列表的尾部T递归调用membermember前两个子句就是在说当X是列表的第一个元素(头部),或它被包含在列表的剩余部分(尾部)中时,X就是该列表的一个成员。member的第三个子句是说X不可能是空列表[]的成员,并因此返回false

    我们将member的求值过程列举如下:

    1. > lists:member(a,[1,2,a,b,c]).
    2. (0)lists:member(a,[1,2,a,b,c])
    3. (1).lists:member(a, [2,a,b,c])
    4. (2)..lists:member(a,[a,b,c])
    5. (2)..true
    6. (1).true
    7. (0)true
    8. true
    9. > lists:member(a,[1,2,3,4]).
    10. (0)lists:member(a, [1,2,3,4])
    11. (1).lists:member(a, [2,3,4])
    12. (2)..lists:member(a, [3,4])
    13. (3)...lists:member(a, [4])
    14. (4)....lists:member(a, [])
    15. (4)....false
    16. (3)...false
    17. (2)..false
    18. (1).false
    19. (0)false
    20. false

    append

    append(A,B)连接两个列表AB

    1. append([H|L1], L2) -> [H|append(L1, L2)];
    2. append([], L) -> L.

    append的第二个子句再明白不过了——将任意列表L追加至空列表之后仍得到L

    第一个子句给出了追加一个非空列表到另一个列表之后的规则。因此,对于:

    1. append([a,b,c], [d,e,f])

    其求值结果为:

    1. [a | append([b,c], [d,e,f])]

    那么append([b,c],[d,e,f])的值又是多少呢?它(当然)是[b,c,d,e,f],因此[a|append([b,c],[d,e,f])]的值就是[a|append([b,c],[d,e,f])],这也是[a,b,c,d,e,f]的另一种写法。

    append的行为如下:

    1. > lists:append([a,b,c],[d,e,f]).
    2. (0)lists:append([a,b,c],[d,e,f])
    3. (1).lists:append([b,c], [d,e,f])
    4. (2)..lists:append([c],[d,e,f])
    5. (3)...lists:append([], [d,e,f])
    6. (3)...[d,e,f]
    7. (2)..[c,d,e,f]
    8. (1).[b,c,d,e,f]
    9. (0)[a,b,c,d,e,f]
    10. [a,b,c,d,e,f]

    reverse

    reverse(L)用于颠倒列表L中的元素顺序。

    1. reverse(L) -> reverse(L, []).
    2.  
    3. reverse([H|T], Acc) ->
    4. reverse(T, [H|Acc]);
    5. reverse([], Acc) ->
    6. Acc.

    reverse(L)利用一个辅助函数reverse/2将最终结果累积到第二个参数中。

    调用reverse(L,Acc)时,若L是一个非空列表,则将L的第一个元素移除并添加Acc的头部。因此对reverse([x,y,z],Acc)的调用将导致reverse([y,z],[x|Acc])的调用。最终reverse/2的第一个参数将归结为一个空列表,这时reverse/2的第二个子句将被匹配并另函数结束。

    整个过程如下:

    1. > lists:reverse([a,b,c,d]).
    2. (0)lists:reverse([a,b,c,d])
    3. (1).lists:reverse([a,b,c,d], [])
    4. (2)..lists:reverse([b,c,d], [a])
    5. (3)...lists:reverse([c,d], [b,a])
    6. (4)....lists:reverse([d], [c,b,a])
    7. (5).....lists:reverse([], [d,c,b,a])
    8. (5).....[d,c,b,a]
    9. (4)....[d,c,b,a]
    10. (3)...[d,c,b,a]
    11. (2)..[d,c,b,a]
    12. (1).[d,c,b,a]
    13. (0)[d,c,b,a]
    14. [d,c,b,a]

    delete_all

    delete_all(X,L)用于删除列表L中出现的所有X

    1. delete_all(X, [X|T]) ->
    2. delete_all(X, T);
    3. delete_all(X, [Y|T]) ->
    4. [Y | delete_all(X, T)];
    5. delete_all(_, []) ->
    6. [].

    delete_all所使用的递归模式与memberappend类似。

    delete_all的第一个子句在要删除的元素出现在列表的头部时匹配。