2012-06-21 8 views
6

リストから2つの要素を取り出し、リストの新しいリストを作成する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

は、リストの内包は不格好になります。リストの理解を作成するには、あなたが話している奇妙な要素であるかどうかを調べる必要があります。ここで私が話しているかのアイデアです:限り、私は承知しているようErlangのは、どのような方法でこれを最適化していないため

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

この1の時間複雑性は、おそらく恐ろしいです。

私はあなたの機能に何か悪いとは思わないし、あなたはそれに固執すべきです。

8

いいえ、リストの理解はそれを行う良い方法ではありません。定義すると、1つの要素につき1回だけ動作します。あなたのコードでは、実際にアキュムレータを使う必要はなく、速度の差は小さく、hereであり、それがなければもっと明確になります。少なくとも私はそう思う。

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

これはErlangのマントラ "let it crash"に従います。 '[a]'の場合 – Tilman

+0

@Tilmanはい、関数は**定義されています**ので、リストに奇数の要素がある場合はエラーです。もちろん、その場合に何が起こるかを定義し、それ以降はそれを処理することができます。 – rvirding