2012-06-21 176 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