Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 466
Jade Allen Avatar asked Jun 21 '12 21:06

Jade Allen


People also ask

What is Erlang list comprehension?

A list comprehension is a mathematical way to construct a list. To do list comprehension we have to use a new operator "<-", "taken from". L = [ X*X || X <- [1,2,3,4] ]. English translation is: build a list L, with elements that have the value X*X, such that X is taken from the list [1,2,3,4].

How do you check if an element is in a list in Erlang?

use List::Util 'first'; print "ok\n" if first {$_ eq $x} @list; grep() will find all the elements that match... in a large list this may waste time. first() will return true as soon as the element is found.

How do I split a list in Erlang?

You can use lists:split/2 for this: divide(L, N) -> divide(L, N, []). divide([], _, Acc) -> lists:reverse(Acc); divide(L, N, Acc) when length(L) < N -> lists:reverse([L|Acc]); divide(L, N, Acc) -> {H,T} = lists:split(N, L), divide(T, N, [H|Acc]).

What is fun in Erlang?

Advertisements. Funs are used to define anonymous functions in Erlang. The general syntax of an anonymous function is given below −


2 Answers

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([]) -> [].
like image 105
rvirding Avatar answered Nov 15 '22 11:11

rvirding


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.

like image 21
Emil Vikström Avatar answered Nov 15 '22 11:11

Emil Vikström