Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang list comprehension, traversing two lists and excluding values

I need to generate a set of coordinates in Erlang. Given one coordinate, say (x,y) I need to generate (x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1, y), (x+1, y+1). Basically all surrounding coordinates EXCEPT the middle coordinate (x,y). To generate all the nine coordinates, I do this currently:

[{X,Y} || X<-lists:seq(X-1,X+1), Y<-lists:seq(Y-1,Y+1)]

But this generates all the values, including (X,Y). How do I exclude (X,Y) from the list using filters in the list comprehension?

like image 644
ErJab Avatar asked Mar 13 '10 04:03

ErJab


People also ask

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

How do I append in Erlang?

Looking at how lists:append/1 or ++ would be implemented in plain Erlang, clearly the first list is copied: append([H|T], Tail) -> [H|append(T, Tail)]; append([], Tail) -> Tail. When recursing and building a list, it is important to ensure that you attach the new elements to the beginning of the list.

How do I check if a list is Erlang empty?

This is the function that is called: set_viewer_values(Value, ViewerSet) -> if ViewerSet /= empty_set -> lists:map(fun(ViewerPid) -> ViewerPid ! {self(), set_value, Value} end, ViewerSet) end.

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


2 Answers

[{X,Y} || X <- lists:seq(X0-1,X0+1),
          Y <- lists:seq(Y0-1,Y0+1), {X,Y} =/= {X0,Y0}].
like image 118
Zed Avatar answered Oct 22 '22 14:10

Zed


I think distinguish between parameters and generated values will help a little:

[{Xc,Yc} || Xc<-lists:seq(X-1,X+1), Yc<-lists:seq(Y-1,Y+1), Xc=/=X orelse Yc=/=Y]

or else

[{Xc,Yc} || Xc<-lists:seq(X-1,X+1), Yc<-lists:seq(Y-1,Y+1)] -- [{X,Y}]
like image 2
Hynek -Pichi- Vychodil Avatar answered Oct 22 '22 15:10

Hynek -Pichi- Vychodil