erlang 如何删除列表中的元素?

z0qdvdin  于 2022-12-16  发布在  Erlang
关注(0)|答案(3)|浏览(262)

我已经实现了一个函数,删除列表中的元素一个接一个:

remove(_,[])->
  [];
remove(Elem, L)->
  Rest = lists:delete(Elem,L),
  remove(Elem,Rest).

但是当我尝试使用这个例子时,它挂起了:

L = [1,2,3,4].
remove(hd(L), [L]).

它有什么问题吗?或者有没有更好的方法从列表的第一个元素开始逐个删除列表中的元素。

mo49yndu

mo49yndu1#

它形成了一个无限循环。首先,调用

remove(1, [1,2,3,4]) ->
    [2,3,4] = lists:delete(1, [1,2,3,4]),
    remove(1, [2,3,4]).

所以你打电话

remove(1, [2,3,4]) ->
    [2,3,4] = lists:delete(1, [2,3,4]),
    remove(1, [2,3,4]).

然后你用同样的输入再次调用它一次又一次。
修复此问题的一种方法是检查lists:delete/2是否返回相同的结果

remove(Elem, L)->
  case lists:delete(Elem,L) of
    L    -> L;
    Rest -> remove(Elem,Rest)
  end.

(函数子句remove(_,[])是不必要的,即使它没有任何危害。)
但还有一种更直接的方法:

remove(_, []) -> [];
remove(H, [H|T]) ->
    remove(H, T);
remove(X, [H|T]) ->
    [H | remove(X, T)].

可以使用列表解析编写:

remove(X, L) ->
    [Y || Y <- L, Y =/= X].

生成的代码将基本相同。

ubof19bj

ubof19bj2#

您还可以使用lists模块,它定义了许多有用的函数。
以这个为例,对于你的情况:

1> A = [1,2,3,4,5,6,7,8,9,10].
[1,2,3,4,5,6,7,8,9,10]
2> B = [2,3,4].
[2,3,4]
3> lists:filter(fun (Elem) -> not lists:member(Elem, B) end, A ).
[1,5,6,7,8,9,10]
qlvxas9a

qlvxas9a3#

简单的答案是A = [1,2,3,3,4] B = [3,4]

A -- B  = C
  
         [1,2,3,3,4] -- [3,4] = [1,2,3].

相关问题