Erlang列表推导 #
一、列表推导概述 #
列表推导式是Erlang中创建列表的简洁语法,源自数学集合表示法。
1.1 数学表示 #
数学中的集合表示:
text
S = {x | x ∈ N, x > 0}
Erlang列表推导:
erlang
S = [X || X <- Numbers, X > 0]
二、基本语法 #
2.1 语法结构 #
erlang
[Expression || Generator, Filter, ...]
- Expression:结果表达式
- Generator:生成器(
Pattern <- List) - Filter:过滤条件
2.2 简单示例 #
erlang
-module(basic_comprehension).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5],
Doubled = [X * 2 || X <- Numbers],
Squared = [X * X || X <- Numbers],
io:format("Doubled: ~p~n", [Doubled]),
io:format("Squared: ~p~n", [Squared]),
ok.
三、生成器 #
3.1 单生成器 #
erlang
-module(single_generator).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
Result = [X || X <- List],
io:format("Result: ~p~n", [Result]),
ok.
3.2 多生成器 #
erlang
-module(multi_generator).
-export([demo/0]).
demo() ->
Xs = [1, 2],
Ys = [a, b],
Pairs = [{X, Y} || X <- Xs, Y <- Ys],
io:format("Pairs: ~p~n", [Pairs]),
ok.
3.3 依赖生成器 #
erlang
-module(dependent_generator).
-export([demo/0]).
demo() ->
Pairs = [{X, Y} || X <- [1, 2, 3], Y <- lists:seq(1, X)],
io:format("Pairs: ~p~n", [Pairs]),
ok.
3.4 模式匹配生成器 #
erlang
-module(pattern_generator).
-export([demo/0]).
demo() ->
Tuples = [{a, 1}, {b, 2}, {c, 3}],
Values = [V || {_, V} <- Tuples],
io:format("Values: ~p~n", [Values]),
ok.
四、过滤器 #
4.1 单过滤器 #
erlang
-module(single_filter).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
Evens = [X || X <- Numbers, X rem 2 =:= 0],
GreaterThan5 = [X || X <- Numbers, X > 5],
io:format("Evens: ~p~n", [Evens]),
io:format("GreaterThan5: ~p~n", [GreaterThan5]),
ok.
4.2 多过滤器 #
erlang
-module(multi_filter).
-export([demo/0]).
demo() ->
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
EvenAndGreaterThan5 = [X || X <- Numbers, X rem 2 =:= 0, X > 5],
io:format("EvenAndGreaterThan5: ~p~n", [EvenAndGreaterThan5]),
ok.
4.3 函数过滤器 #
erlang
-module(function_filter).
-export([demo/0]).
demo() ->
Strings = ["hello", "world", "erlang", "programming"],
LongWords = [S || S <- Strings, length(S) > 5],
ContainsE = [S || S <- Strings, string:find(S, "e") =/= nomatch],
io:format("LongWords: ~p~n", [LongWords]),
io:format("ContainsE: ~p~n", [ContainsE]),
ok.
五、嵌套推导 #
5.1 展平嵌套列表 #
erlang
-module(flatten_nested).
-export([demo/0]).
demo() ->
Nested = [[1, 2], [3, 4], [5, 6]],
Flattened = [X || SubList <- Nested, X <- SubList],
io:format("Flattened: ~p~n", [Flattened]),
ok.
5.2 深度嵌套 #
erlang
-module(deep_nested).
-export([demo/0]).
demo() ->
Deep = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]],
Flattened = [X || L1 <- Deep, L2 <- L1, X <- L2],
io:format("Flattened: ~p~n", [Flattened]),
ok.
5.3 条件嵌套 #
erlang
-module(conditional_nested).
-export([demo/0]).
demo() ->
Data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
Result = [X || SubList <- Data, length(SubList) > 2, X <- SubList, X > 3],
io:format("Result: ~p~n", [Result]),
ok.
六、二进制推导 #
6.1 二进制到列表 #
erlang
-module(binary_to_list_comp).
-export([demo/0]).
demo() ->
Binary = <<1, 2, 3, 4, 5>>,
List = [X || X <- Binary],
io:format("List: ~p~n", [List]),
ok.
6.2 列表到二进制 #
erlang
-module(list_to_binary_comp).
-export([demo/0]).
demo() ->
List = [1, 2, 3, 4, 5],
Binary = << <<X>> || X <- List >>,
io:format("Binary: ~p~n", [Binary]),
ok.
6.3 二进制转换 #
erlang
-module(binary_transform).
-export([demo/0]).
demo() ->
Binary = <<1, 2, 3, 4, 5>>,
Doubled = << <<(X * 2)>> || X <- Binary >>,
io:format("Doubled: ~p~n", [Doubled]),
ok.
6.4 位级推导 #
erlang
-module(bit_comprehension).
-export([demo/0]).
demo() ->
Binary = <<16#AB:8>>,
Nibbles = [N || <<N:4>> <= Binary],
io:format("Nibbles: ~p~n", [Nibbles]),
ok.
七、实际应用 #
7.1 数据转换 #
erlang
-module(data_transform).
-export([users_to_names/1, filter_active/1]).
users_to_names(Users) ->
[Name || #{name := Name} <- Users].
filter_active(Users) ->
[User || #{active := true} = User <- Users].
7.2 矩阵操作 #
erlang
-module(matrix_ops).
-export([transpose/1, multiply/2]).
transpose(Matrix) ->
[[element(I, list_to_tuple(Row)) || Row <- Matrix]
|| I <- lists:seq(1, length(hd(Matrix)))].
multiply(A, B) ->
BT = transpose(B),
[[lists:sum([X * Y || {X, Y} <- lists:zip(Row, Col)])
|| Col <- BT]
|| Row <- A].
7.3 字符串处理 #
erlang
-module(string_processing).
-export([uppercase_all/1, filter_words/2]).
uppercase_all(Strings) ->
[string:uppercase(S) || S <- Strings].
filter_words(Strings, MinLength) ->
[S || S <- Strings, length(S) >= MinLength].
7.4 配置处理 #
erlang
-module(config_processing).
-export([get_enabled/1, get_values/2]).
get_enabled(Configs) ->
[Name || {Name, #{enabled := true}} <- Configs].
get_values(Configs, Key) ->
[Value || {_, Map} <- Configs, {K, Value} <- maps:to_list(Map), K =:= Key].
八、性能考虑 #
8.1 与map/filter比较 #
erlang
-module(perf_comparison).
-export([with_comprehension/1, with_map_filter/1]).
with_comprehension(List) ->
[X * 2 || X <- List, X > 0].
with_map_filter(List) ->
lists:map(fun(X) -> X * 2 end,
lists:filter(fun(X) -> X > 0 end, List)).
8.2 避免重复计算 #
erlang
-module(avoid_recompute).
-export([bad/1, good/1]).
bad(List) ->
[{X, X * X} || X <- List, X * X > 10].
good(List) ->
[{X, X2} || X <- List, X2 <- [X * X], X2 > 10].
九、总结 #
本章学习了:
- 列表推导语法
- 生成器
- 过滤器
- 嵌套推导
- 二进制推导
- 实际应用
- 性能考虑
准备好学习模块了吗?让我们进入下一章。
最后更新:2026-03-27