2010-10-22 189 views
2

如何根据每个元素的标签对Erlang中的列表进行排序?在Erlang中对列表进行排序

如果我有一个进程循环并从多个进程接收单个值,然后我想根据标签(这是一个索引)作为一个元素接收安排列表。

如何在不使用BIF的情况下做到这一点?

我目前做了以下工作,但想要在添加元素时安排列表,例如使用标记进行插入排序。

fibLoop(calcData) -> 
receive 
{Number, Tag} -> 
fibLoop([{Number, Tag}|calcData]); 
+0

如果您需要在中间结构中定期插入东西,那么* *列表几乎肯定是错误的数据结构。对于这样的应用程序,适当类型的* tree *是一个更好的选择。 – ndim 2010-10-24 03:37:15

回答

2

像这样的东西可能会工作:

insert({_, Tag} = Data, [{_,HTag}|_] = List) when Tag >= HTag -> 
    [Data | List]; 
insert(Data, [H | T]) -> 
    [H | insert(Data, T)]; 
insert(Data, []) -> 
    [Data]. 
+0

谢谢。如果我只想将这些数字作为输出,那么一旦排序,就移除标签(第二个元组元素)并返回一个数字列表? – jarryd 2010-10-22 10:18:29

+0

你可以使用'lists:map()' – ZeissS 2010-10-22 11:44:10

+0

一个简单的删除标签的方法是使用列表理解, [K || {K,V} < - [{1,a},{2,b}]] - > [1,2]。 – bjnortier 2010-10-22 12:18:33

2

有多种方法可以做到你想要什么,有点取决于您要使用的值以后什么。

简单的解决方案是使用gb_trees。 gb_trees是一个可以使用迭代器循环的排序结构。

或者如果你想保持简单,并有一个列表,你可以使用orddict(或可能ordsets)。

orddict:store(Number, Tag, CalcData) 

将{Number,Tag}插入到有序列表中。有关更多信息,请参阅orddict的文档。

要获得列表中最小的值,您可以使用hd/1,并获得最大的列表:last/1(不是我推荐的列表:最后,介意你)。