2010-10-22 112 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(不是我推薦的列表:最後,介意你)。