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