Erlang中如何检查点记录列表是否包含指定点记录?
Erlang contains_point函数实现方案
问题分析
你写的代码里有两个核心问题:
- 变量遮蔽:fun里的参数
Point和外部函数的参数重名,导致外部传入的Point变量根本没被用到,所以出现警告。 - 逻辑冗余且错误:用
lists:any嵌套lists:member完全没必要,而且这个逻辑会把列表里的每个元素拿去检查是否在列表中,最终结果永远是true(除非列表为空),完全不符合你要判断指定Point是否存在的需求。
最简实现方式
Erlang的记录在进行比较时,会严格匹配结构和所有字段的值,所以直接用lists:member/2就能满足需求:
contains_point(Point, List) -> lists:member(Point, List).
这个函数会遍历传入的List,检查是否存在和Point完全相同的记录,存在返回true,否则返回false,完全符合你的要求。
手动递归实现(如果想自己实现遍历逻辑)
如果你希望手动实现遍历而非依赖lists模块,也可以用递归:
contains_point(_Point, []) -> false; contains_point(Point, [Current|Rest]) -> case Current of Point -> true; _ -> contains_point(Point, Rest) end.
- 空列表直接返回
false(没有元素可匹配) - 每次取列表的第一个元素
Current和目标Point比较,匹配就返回true,否则递归检查剩余的列表Rest
原代码错误拆解
你的原代码:
contains_point(Point, List)-> Found = fun(Point) -> lists:member(Point, List) end, case lists:any(Found, List) of true -> yes; false -> no end.
fun(Point)里的Point是局部参数,覆盖了外部函数的Point参数,导致外部的Point从未被使用,触发警告。lists:any(Found, List)会把List里的每个元素传给Found函数,相当于每次判断「当前元素是否在List里」,这必然返回true(除非List为空),完全偏离了判断「指定Point是否在List里」的需求。
内容的提问来源于stack exchange,提问作者ga43
相关产品推荐
相关产品推荐

