2011-03-07 32 views
2

我想將[z,z,a,z,z,a,a,z]轉換爲[{z,2},{a,1},{z,2},{a,2},{z,1}]。我該怎麼做?列表中的元組轉換

所以,我需要積累以前的值,它的計數器和元組列表。

我已經創造紀錄

-record(acc, {previous, counter, tuples}). 

重新定義

listToTuples([]) -> []; 
listToTuples([H | Tail]) -> 
    Acc = #acc{previous=H, counter=1}, 
    listToTuples([Tail], Acc). 

但我有一些麻煩

listToTuples([H | Tail], Acc) -> 
    case H == Acc#acc.previous of 
     true -> 
     false -> 
    end. 

回答

8

,如果你在倒車建立你的答案(ACC),該以前將是該名單的負責人。

這裏的如何,我會做到這一點 -

list_pairs(List) -> list_pairs(List, []). 

list_pairs([], Acc) -> lists:reverse(Acc); 
list_pairs([H|T], [{H, Count}|Acc]) -> list_pairs(T, [{H, Count+1}|Acc]); 
list_pairs([H|T], Acc) -> list_pairs(T, [{H, 1}|Acc]). 

(我希望有人現在將單行列表解析版本遵循..)

+0

我懷疑你可以用列表理解來做到這一點。至少需要摺疊。 – 2011-03-07 13:10:45

5

我會繼續在道路建設該列表反過來。注意在第一行上與X匹配的模式。

F = fun(X,[{X,N}|Rest]) -> [{X,N+1}|Rest]; 
     (X,Rest)   -> [{X,1}|Rest] end. 

lists:foldr(F,[],List). 
+1

使用'lists:foldr/3',你在家。 ;) – 2011-03-07 16:39:00

+0

謝謝,現在用foldr編輯 – 2011-03-07 22:11:38

+0

對於'lists:foldr/3',你並不是真的在反向列表中構建,至少與你調用累加器並調用'lists時的意思不一樣:反轉/ 1'就可以了。 'lists:foldr'只是從右到左在列表上工作,所以它按照相反的順序處理所有的元素,這是**定義的。這不是尾遞歸,並不總是如此糟糕的事情。這在文檔中提到。 – rvirding 2011-03-08 02:46:02

2

我會親自使用lists:foldr/3或手工的東西,如做到這一點:

list_to_tuples([H|T]) -> list_to_tuples(T, H, 1); 
list_to_tuples([]) -> []. 

list_to_tuples([H|T], H, C) -> list_to_tuples(T, H, C+1); 
list_to_tuples([H|T], P, C) -> [{P,C}|list_to_tuples(T, H, 1); 
list_to_tuples([], P, C) -> [{P,C}]. 

使用兩個蓄能器爲您節省不必要的構建和拉開一個元組列表中的每個元素。我覺得寫得更清楚。