18

如何从 Erlang 的列表中删除重复项?

假设我有一个类似的列表:

[1,1,2,3,4,5,5,6]

我怎样才能得到:

[1,2,3,4,5,6]
4

6 回答 6

42

您可以使用sets,例如:

my_nonDuplicate_list1() ->
    List = [1,1,2,3,4,5,5,6],
    Set = sets:from_list(List),
    sets:to_list(Set).

这将返回[1,2,3,4,5],不再重复,但很可能未排序。

不使用的另一种可能性sets是:

my_nonDuplicate_list2() ->
    List = [1,1,2,3,4,5,5,6],
    lists:usort(List).

在这种情况下,它返回[1,2,3,4,5],不再重复和排序。

于 2012-12-02T22:15:31.903 回答
18

对于那些希望保留列表顺序的人:

remove_dups([])    -> [];
remove_dups([H|T]) -> [H | [X || X <- remove_dups(T), X /= H]].
于 2014-03-02T20:39:36.060 回答
1

Preserve the order of the elements帮助您学习如何操作列表的可能解决方案将涉及两个功能:

delete_all(Item, [Item | Rest_of_list]) ->
    delete_all(Item, Rest_of_list);
delete_all(Item, [Another_item| Rest_of_list]) ->
    [另一个项目 | delete_all(Item, Rest_of_list)];
删除全部(_,[])-> []。

删除重复项(列表)-> 删除(列表,[])。
移除([],这个)-> 列表:反向(这个);
移除([A|Tail],Acc)->
    删除(删除全部(A,尾巴),[A|Acc])。

去测试,

Eshell V5.9(使用 ^G 中止)
1> mymod:remove_duplicates([1,2,3,1,2,4,1,2,1])。
[1,2,3,4]
2>

于 2012-12-03T08:27:53.543 回答
0

我一开始会做这样的事情来保持秩序,虽然不推荐。请记住,这AddedStuff ++ Accumulator很好,但Accumulator ++ AddedStuff确实很糟糕。

rm_dup(List) ->
    lists:foldl(
        fun(Elem, Acc) ->
            case lists:member(Elem, Acc) of
                true ->
                    Acc;
                false ->
                    Acc ++ [Elem]
            end
        end, [], List
    ).

如果您想保留订单,此解决方案效率更高:

rm_dup(List) ->
    lists:reverse(lists:foldl(
        fun(Elem, Acc) ->
            case lists:member(Elem, Acc) of
                true ->
                    Acc;
                false ->
                    [Elem] ++ Acc
            end
        end, [], List
    )).
于 2015-09-19T19:52:54.353 回答
0

模块sets有两个可以组合并以有效方式完成工作的函数:sets:from_list/1返回一个包含列表所有元素的集合(定义中没有重复的元素),并sets:to_list/1返回一个包含集合元素的列表。这是一个使用示例:

4> sets:to_list(sets:from_list([1,1,2,3,4,5,5,6])).
[3,6,2,5,1,4]

我们可以将函数定义为

nub(L) -> sets:to_list(sets:from_list(L)).
于 2016-06-02T09:40:14.810 回答
0

在我看来,最好的选择是使用lists:usort()

但是,如果您不想使用 BIF,并且希望对列表进行排序,我建议使用快速排序的版本,在此实现中,您将获得排序后的列表而没有重复值。

unique_sort([]) -> [];
unique_sort([Pivot|T]) ->
unique_sort ([X || X <- T, X < Pivot ) ]++
[Pivot] ++
unique_sort ([X || X <- T, X > Pivot ]).
于 2016-07-03T21:45:01.650 回答