Erlang:如何实现Erlang列表推导式?

6

实现一个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 水平不够,无法想出解决方法。有什么建议吗?谢谢。
2个回答

8
不,列表推导式不是做这件事的好方法,因为它们按定义只能一次处理一个元素。在您的代码中,实际上没有必要使用累加器,速度差异很小,在这里,并且没有累加器更清晰明了。至少我认为是这样的。
pairs([A,B|L]) ->
    [[A,B]|pairs(L)];
pairs([]) -> [].

1
这遵循Erlang的口号“让它崩溃”,例如对于情况 [a] - Tilman
@Tilman 是的,该函数被定义为接受元素对,因此如果列表中有奇数个元素,则会出现错误。当然,您始终可以定义在这种情况下要发生什么并在处理后处理它。 - rvirding

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].

这个函数的时间复杂度可能很糟糕,因为据我所知Erlang并没有以任何方式进行优化。

我认为你的函数没有问题,你应该坚持使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接