Reputation: 365
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
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
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