Jade Allen
Jade Allen

Reputation: 365

Erlang : how to implement Erlang list comprehension ?

Implement an Erlang list comprehension that takes two elements from a list and makes a new list of lists.

I have this code

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

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

which works fine:

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

but it seems like I should be able to implement this as a list comprehension. My Erlang-fu is too weak to come up with it.

Any suggestions?

Thanks

Upvotes: 6

Views: 1047

Answers (2)

rvirding
rvirding

Reputation: 20916

No, a list comprehension would not be a good way to do that, by definition they only work on one element a a time. In your code there is really no need to use an accumulator, the difference in speed is small, here, and it becomes clearer without it. I think so at least.

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

Upvotes: 8

Emil Vikström
Emil Vikström

Reputation: 91932

A list comprehension will be clunky because it inevitably must do something for every element of the list. To create a list comprehension you must thus try to find out if it's an even or odd element you are talking to. Here's an idea of what I'm talking about:

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

The time complexity on this one is probably horrible because as far as I'm aware Erlang does not optimize this in any way.

I don't think there's anything wrong with your function and you should stick to it.

Upvotes: 1

Related Questions