【问题标题】:Remove duplicate elements from a list in Erlang从 Erlang 中的列表中删除重复元素
【发布时间】:2012-11-20 07:45:29
【问题描述】:

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

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

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

如何获得:

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

【问题讨论】:

  • 输入列表是否已经排序?
  • 顺序重要吗?我可以重新排列元素吗?

标签: list erlang


【解决方案1】:

您可以使用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],不再重复和排序。

【讨论】:

  • 这在幕后的效率如何?我假设usort 是 N log N,集合是线性的吗?我想从一个列表到一个集合是线性的,反之亦然,所以也许第一个选项更有效(如果不需要排序)。
【解决方案2】:

模块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)).

【讨论】:

  • 请在您的回答中添加说明
【解决方案3】:

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

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

unique_sort([]) -> [];
unique_sort([Pivot|T]) ->
unique_sort ([X || X <- T, X < Pivot ) ]++
[Pivot] ++
unique_sort ([X || X <- T, X > Pivot ]).

【讨论】:

    【解决方案4】:

    我会首先做这样的事情来保持秩序,尽管它不推荐。请记住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
        )).
    

    【讨论】:

      【解决方案5】:

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

      remove_dups([])    -> [];
      remove_dups([H|T]) -> [H | [X || X <- remove_dups(T), X /= H]].
      

      【讨论】:

      • 这应该是公认的答案,想要一个列表的distinctremove_dups 函数的要点是保留顺序,否则使用集合或有序集合始终是一种选择。跨度>
      【解决方案6】:

      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>

      【讨论】:

        猜你喜欢
        • 2015-01-05
        • 2012-05-09
        • 2018-01-01
        • 2012-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多