2012-06-21 75 views
6

實現一個Erlang列表理解,它從列表中獲取兩個元素並創建一個新的列表列表。Erlang:如何實現Erlang列表理解?

我有這樣的代碼

pair([], Acc) -> lists:reverse(Acc); 

pair(L, Acc0) -> 
    [ A, B | T ] = L, 
    Acc = [ [A, B] | Acc0 ], 
    pair(T, Acc). 

的正常工作:

7> l:pair(lists:seq(1,6), []). 
[[1,2],[3,4],[5,6]] 

,但好像我應該能夠實現這個作爲一個列表理解。我的Erlang-fu太弱,無法提出。

有什麼建議嗎?

感謝

回答

1

列表理解將是笨重的,因爲它不可避免地必須爲做點什麼列表中的每一個元素。爲了創建一個列表理解,您必須嘗試查明它是否與您正在交談的是偶數或奇數元素。下面是我在談論的一個想法:

pair(L) -> 
    L2 = lists:zip(lists:seq(1, length(L)), L), 
    [[A, B] || {Ai, A} <- L2, {Bi, B} <- L2, 
      Ai rem 2 == 1, Bi rem 2 == 0, Ai + 1 == Bi]. 

在這一個時間複雜度可能是可怕的,因爲據我所知二郎不優化這種以任何方式。

我不認爲你的功能有什麼問題,你應該堅持下去。

8

不,一個列表理解不會是一個好的方法來做到這一點,根據定義,他們只能在一個元素上工作一次。在你的代碼中,真的不需要使用累加器,速度的差異很小,here,沒有它就變得更清晰。至少我這麼認爲。

pairs([A,B|L]) -> 
    [[A,B]|pairs(L)]; 
pairs([]) -> []. 
+1

這跟着Erlang的口頭禪「讓它崩潰」,例如,對於'[a]'的情況。 – Tilman

+0

@Tilman是的,該函數是**定義的**來獲取元素對,所以如果在列表中有奇數個元素時是錯誤的。你當然可以總是定義在這種情況下會發生什麼,然後處理它。 – rvirding