Erlang列表 #
一、列表概述 #
列表是Erlang中最常用的数据结构之一,用于存储有序的元素集合。
1.1 列表的本质 #
列表由头(Head)和尾(Tail)组成,尾也是一个列表:
erlang
-module(list_essence).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
[Head | Tail] = List,
io:format("List: ~p~n", [List]),
io:format("Head: ~p~n", [Head]),
io:format("Tail: ~p~n", [Tail]),
ok.
1.2 列表定义 #
erlang
-module(list_def).
-export([demo/0]).
demo() ->
Empty = [],
Numbers = [1, 2, 3],
Mixed = [1, "hello", atom, {tuple}],
Nested = [[1, 2], [3, 4]],
io:format("Empty: ~p~n", [Empty]),
io:format("Numbers: ~p~n", [Numbers]),
io:format("Mixed: ~p~n", [Mixed]),
io:format("Nested: ~p~n", [Nested]),
ok.
二、列表构造 #
2.1 使用|操作符 #
erlang
-module(list_construct).
-export([demo/0]).
demo() ->
List1 = [1 | [2, 3]],
List2 = [1, 2 | [3]],
List3 = [1, 2, 3 | []],
io:format("List1: ~p~n", [List1]),
io:format("List2: ~p~n", [List2]),
io:format("List3: ~p~n", [List3]),
ok.
2.2 添加元素 #
erlang
-module(add_element).
-export([demo/0]).
demo() ->
List = [2, 3, 4],
NewList = [1 | List],
io:format("Original: ~p~n", [List]),
io:format("After add: ~p~n", [NewList]),
ok.
2.3 列表连接 #
erlang
-module(list_concat).
-export([demo/0]).
demo() ->
List1 = [1, 2],
List2 = [3, 4],
Combined = List1 ++ List2,
io:format("List1: ~p~n", [List1]),
io:format("List2: ~p~n", [List2]),
io:format("Combined: ~p~n", [Combined]),
ok.
2.4 列表减法 #
erlang
-module(list_subtract).
-export([demo/0]).
demo() ->
List1 = [1, 2, 3, 2, 1],
List2 = [1, 2],
Result = List1 -- List2,
io:format("List1: ~p~n", [List1]),
io:format("List2: ~p~n", [List2]),
io:format("Result: ~p~n", [Result]),
ok.
三、列表模式匹配 #
3.1 提取头尾 #
erlang
-module(list_pattern).
-export([demo/0]).
demo() ->
[H | T] = [1, 2, 3, 4, 5],
io:format("Head: ~p~n", [H]),
io:format("Tail: ~p~n", [T]),
[A, B | Rest] = [1, 2, 3, 4, 5],
io:format("A: ~p~n", [A]),
io:format("B: ~p~n", [B]),
io:format("Rest: ~p~n", [Rest]),
ok.
3.2 匹配特定元素 #
erlang
-module(match_specific).
-export([demo/0]).
demo() ->
[First, Second, Third] = [a, b, c],
io:format("First: ~p~n", [First]),
io:format("Second: ~p~n", [Second]),
io:format("Third: ~p~n", [Third]),
ok.
3.3 忽略元素 #
erlang
-module(ignore_elements).
-export([first/1, second/1, last/1]).
first([H | _]) -> H.
second([_, H | _]) -> H.
last([H]) -> H;
last([_ | T]) -> last(T).
四、lists模块 #
4.1 基本函数 #
erlang
-module(lists_basic).
-export([demo/0]).
demo() ->
List = [3, 1, 4, 1, 5, 9, 2, 6],
Len = length(List),
Rev = lists:reverse(List),
Sort = lists:sort(List),
Sum = lists:sum(List),
io:format("Original: ~p~n", [List]),
io:format("Length: ~p~n", [Len]),
io:format("Reverse: ~p~n", [Rev]),
io:format("Sort: ~p~n", [Sort]),
io:format("Sum: ~p~n", [Sum]),
ok.
4.2 查找函数 #
erlang
-module(lists_find).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
Member = lists:member(3, List),
Nth = lists:nth(3, List),
Pos = lists:position(3, List),
Keyfind = lists:keyfind(a, 1, [{a, 1}, {b, 2}]),
io:format("member(3): ~p~n", [Member]),
io:format("nth(3): ~p~n", [Nth]),
io:format("position(3): ~p~n", [Pos]),
io:format("keyfind(a): ~p~n", [Keyfind]),
ok.
4.3 过滤函数 #
erlang
-module(lists_filter).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
Even = lists:filter(fun(X) -> X rem 2 =:= 0 end, List),
Odd = lists:filter(fun(X) -> X rem 2 =:= 1 end, List),
Partition = lists:partition(fun(X) -> X > 5 end, List),
io:format("Original: ~p~n", [List]),
io:format("Even: ~p~n", [Even]),
io:format("Odd: ~p~n", [Odd]),
io:format("Partition: ~p~n", [Partition]),
ok.
4.4 映射函数 #
erlang
-module(lists_map).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
Doubled = lists:map(fun(X) -> X * 2 end, List),
Squared = lists:map(fun(X) -> X * X end, List),
io:format("Original: ~p~n", [List]),
io:format("Doubled: ~p~n", [Doubled]),
io:format("Squared: ~p~n", [Squared]),
ok.
4.5 折叠函数 #
erlang
-module(lists_fold).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
Sum = lists:foldl(fun(X, Acc) -> X + Acc end, 0, List),
Product = lists:foldl(fun(X, Acc) -> X * Acc end, 1, List),
Reversed = lists:foldl(fun(X, Acc) -> [X | Acc] end, [], List),
io:format("Original: ~p~n", [List]),
io:format("Sum: ~p~n", [Sum]),
io:format("Product: ~p~n", [Product]),
io:format("Reversed: ~p~n", [Reversed]),
ok.
4.6 常用函数列表 #
| 函数 | 说明 |
|---|---|
length/1 |
列表长度 |
hd/1 |
获取头元素 |
tl/1 |
获取尾列表 |
lists:reverse/1 |
反转列表 |
lists:sort/1 |
排序 |
lists:sum/1 |
求和 |
lists:concat/1 |
连接元素 |
lists:flatten/1 |
展平嵌套列表 |
lists:member/2 |
检查成员 |
lists:nth/2 |
获取第N个元素 |
lists:append/2 |
连接列表 |
lists:delete/2 |
删除元素 |
lists:filter/2 |
过滤 |
lists:map/2 |
映射 |
lists:foldl/3 |
左折叠 |
lists:foldr/3 |
右折叠 |
lists:foreach/2 |
遍历执行 |
lists:all/2 |
全部满足 |
lists:any/2 |
任一满足 |
lists:zip/2 |
配对 |
lists:unzip/1 |
解配对 |
五、递归处理列表 #
5.1 遍历列表 #
erlang
-module(list_traverse).
-export([print_all/1]).
print_all([]) -> ok;
print_all([H | T]) ->
io:format("~p~n", [H]),
print_all(T).
5.2 计算长度 #
erlang
-module(list_length).
-export([my_length/1]).
my_length([]) -> 0;
my_length([_ | T]) -> 1 + my_length(T).
5.3 求和 #
erlang
-module(list_sum).
-export([my_sum/1]).
my_sum([]) -> 0;
my_sum([H | T]) -> H + my_sum(T).
5.4 反转 #
erlang
-module(list_reverse).
-export([my_reverse/1]).
my_reverse(List) -> my_reverse(List, []).
my_reverse([], Acc) -> Acc;
my_reverse([H | T], Acc) -> my_reverse(T, [H | Acc]).
5.5 过滤 #
erlang
-module(list_filter).
-export([my_filter/2]).
my_filter(_, []) -> [];
my_filter(Pred, [H | T]) ->
case Pred(H) of
true -> [H | my_filter(Pred, T)];
false -> my_filter(Pred, T)
end.
5.6 映射 #
erlang
-module(list_map).
-export([my_map/2]).
my_map(_, []) -> [];
my_map(Fun, [H | T]) -> [Fun(H) | my_map(Fun, T)].
六、列表推导式 #
6.1 基本语法 #
erlang
-module(list_comprehension).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
Doubled = [X * 2 || X <- Numbers],
Squared = [X * X || X <- Numbers],
Evens = [X || X <- Numbers, X rem 2 =:= 0],
io:format("Original: ~p~n", [Numbers]),
io:format("Doubled: ~p~n", [Doubled]),
io:format("Squared: ~p~n", [Squared]),
io:format("Evens: ~p~n", [Evens]),
ok.
6.2 多个生成器 #
erlang
-module(multi_generator).
-export([demo/0]).
demo() ->
Pairs = [{X, Y} || X <- [1, 2, 3], Y <- [a, b]],
io:format("Pairs: ~p~n", [Pairs]),
ok.
6.3 带条件 #
erlang
-module(with_guard).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
EvenSquares = [X * X || X <- Numbers, X rem 2 =:= 0],
io:format("Even squares: ~p~n", [EvenSquares]),
ok.
6.4 嵌套列表 #
erlang
-module(nested_comp).
-export([demo/0]).
demo() ->
Nested = [[1, 2], [3, 4], [5, 6]],
Flattened = [X || SubList <- Nested, X <- SubList],
io:format("Nested: ~p~n", [Nested]),
io:format("Flattened: ~p~n", [Flattened]),
ok.
七、列表与字符串 #
7.1 字符串是列表 #
erlang
-module(string_as_list).
-export([demo/0]).
demo() ->
Str = "hello",
[H | T] = Str,
io:format("String: ~p~n", [Str]),
io:format("Head char: ~c (~p)~n", [H, H]),
io:format("Tail: ~s~n", [T]),
ok.
7.2 字符串处理 #
erlang
-module(string_list_ops).
-export([uppercase/1, lowercase/1]).
uppercase(Str) -> [char:to_upper(C) || C <- Str].
lowercase(Str) -> [char:to_lower(C) || C <- Str].
八、性能考虑 #
8.1 头部操作高效 #
erlang
-module(perf_head).
-export([demo/0]).
demo() ->
List = lists:seq(1, 10000),
AddHead = [0 | List],
AddTail = List ++ [0],
io:format("Add to head: fast~n"),
io:format("Add to tail: slow~n"),
ok.
8.2 避免频繁++ #
erlang
-module(avoid_concat).
-export([bad/1, good/1]).
bad(List) ->
lists:foldl(fun(X, Acc) -> Acc ++ [X] end, [], List).
good(List) ->
lists:reverse(lists:foldl(fun(X, Acc) -> [X | Acc] end, [], List)).
8.3 使用尾递归 #
erlang
-module(tail_recursive).
-export([sum_bad/1, sum_good/1]).
sum_bad([]) -> 0;
sum_bad([H | T]) -> H + sum_bad(T).
sum_good(List) -> sum_good(List, 0).
sum_good([], Acc) -> Acc;
sum_good([H | T], Acc) -> sum_good(T, H + Acc).
九、实用函数 #
9.1 查找元素 #
erlang
-module(find_utils).
-export([find/2, find_index/2]).
find(_, []) -> not_found;
find(Value, [Value | _]) -> {found, Value};
find(Value, [_ | T]) -> find(Value, T).
find_index(Value, List) -> find_index(Value, List, 1).
find_index(_, [], _) -> not_found;
find_index(Value, [Value | _], Index) -> {found, Index};
find_index(Value, [_ | T], Index) -> find_index(Value, T, Index + 1).
9.2 去重 #
erlang
-module(unique).
-export([unique/1]).
unique(List) -> unique(List, []).
unique([], Acc) -> lists:reverse(Acc);
unique([H | T], Acc) ->
case lists:member(H, Acc) of
true -> unique(T, Acc);
false -> unique(T, [H | Acc])
end.
9.3 分组 #
erlang
-module(group).
-export([group_by/2]).
group_by(N, List) when N > 0 -> group_by(N, List, []).
group_by(_, [], Acc) -> lists:reverse(Acc);
group_by(N, List, Acc) ->
{Group, Rest} = split_n(N, List),
group_by(N, Rest, [Group | Acc]).
split_n(N, List) -> split_n(N, List, []).
split_n(0, List, Acc) -> {lists:reverse(Acc), List};
split_n(_, [], Acc) -> {lists:reverse(Acc), []};
split_n(N, [H | T], Acc) -> split_n(N - 1, T, [H | Acc]).
十、总结 #
本章学习了:
- 列表的本质和定义
- 列表构造和操作
- 列表模式匹配
- lists模块函数
- 递归处理列表
- 列表推导式
- 性能考虑
- 实用函数
准备好学习元组类型了吗?让我们进入下一章。
最后更新:2026-03-27