You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Erlang列表推导+模式匹配筛选后续元素为X的列表元素?

如何用Erlang找出列表中所有后续元素为指定值X的元素

嘿,这个需求挺常见的!咱们来聊聊怎么用Erlang实现它,尤其是你关心的列表推导式结合模式匹配的方法~

首先得搞清楚你之前的写法为什么得到空列表:
你尝试的代码是:

[X||[H1|[H2|_]]=X <- [1,2,3,4]].

这里的问题出在生成器部分X <- [1,2,3,4]——它是把列表里的单个元素(1、2、3、4分别赋值给X),而模式[H1|[H2|_]]需要匹配的是至少包含两个元素的列表,单个数字肯定匹配不上,所以所有元素都被过滤掉,结果自然是空列表啦。

那正确的做法是什么呢?核心思路是:我们需要遍历列表中的相邻元素对,然后筛选出第二个元素等于X的那些对,再取出对应的第一个元素。

方法1:用列表推导式结合lists:zip(最简洁)

Erlang的lists:zip/2函数可以把两个列表打包成元组列表,我们可以用原列表和它的尾部(tl(L))来生成相邻元素对:

L = [1,2,3,4,3],
X = 3,
[H || {H, X} <- lists:zip(L, tl(L))].

运行这段代码会得到[2,4],完美符合需求!

解释一下:

  • tl(L)会把原列表去掉第一个元素,比如tl([1,2,3,4,3])得到[2,3,4,3]
  • lists:zip(L, tl(L))会生成[{1,2}, {2,3}, {3,4}, {4,3}]
  • 列表推导式里的模式{H, X}会匹配所有第二个元素等于X的元组,然后取出H,就是我们要找的元素。

方法2:自定义递归函数(更直观)

如果不想用lists:zip,也可以写一个递归函数来遍历列表,手动匹配相邻元素:

find_predecessors(X, L) -> find_predecessors(X, L, []).

% 终止条件:空列表或只有一个元素时,反转累加器返回
find_predecessors(_, [], Acc) -> lists:reverse(Acc);
find_predecessors(_, [_], Acc) -> lists:reverse(Acc);

% 当第二个元素等于X时,把第一个元素加入累加器
find_predecessors(X, [H1, H2 | T], Acc) when H2 =:= X ->
    find_predecessors(X, [H2 | T], [H1 | Acc]);

% 否则继续遍历
find_predecessors(X, [_, H2 | T], Acc) ->
    find_predecessors(X, [H2 | T], Acc).

调用find_predecessors(3, [1,2,3,4,3])也会得到[2,4]。

回到你的疑问:列表推导式+模式匹配可行吗?

当然可行!但前提是你得把数据转换成能被模式匹配的结构(比如相邻元素对),而不是直接遍历原列表的单个元素。lists:zip帮我们做了这个转换,让后续的模式匹配和筛选变得非常简洁。

所以不是列表推导式和模式匹配的“魔力”不够,而是需要先给它们合适的数据结构来发挥作用😉

内容的提问来源于stack exchange,提问作者alexakarpov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:08:48