2012-12-02 79 views
11

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

假设我有这样一个清单:

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

我如何获得:

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

输入表是否已排序? –

+0

而且命令很重要吗?我可以重新排列元素吗? –

回答

33

你可以使用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],没有更多的重复和排序。

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]) -> 
    [Another_item | delete_all(Item, Rest_of_list)]; 
delete_all(_, []) -> []. 

remove_duplicates(List)-> removing(List,[]). 
removing([],This) -> lists:reverse(This); 
removing([A|Tail],Acc) -> 
    removing(delete_all(A,Tail),[A|Acc]). 

要进行测试,

 
Eshell V5.9 (abort with ^G) 
1> mymod:remove_duplicates([1,2,3,1,2,4,1,2,1]). 
[1,2,3,4] 
2> 

8

而对于那些希望保留的顺序清单:

remove_dups([]) -> []; 
remove_dups([H|T]) -> [H | [X || X <- remove_dups(T), X /= H]]. 
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 
    )). 
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)). 
+3

请将解释添加到您的答案 –

+0

我编辑了我的答案,我希望就够了。 – aherranz

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 ]).