[erlang-questions] Nested for-loops, there has to be a better way to do this

kiszl <>
Wed Jul 29 08:25:24 CEST 2009


Hi,

Do you mean something like this?


--------------------

-module(loop).

-export([loop/2]).
-export([callback/1]).

callback(Numbers) ->
    io:format("~p~n", [Numbers]).

loop(Callback, Limits) ->
    loop(Limits, lists:duplicate(length(Limits), 1), Callback).

loop(Limits, Current, Callback) ->
    Callback(Current),
    case increment(Limits, Current) of
        finished ->
            ok;
        NewCurrent ->
        loop(Limits, NewCurrent, Callback)
    end.

increment(Limits, Current) ->
    increment(Limits, Current, []).

increment([], [], _) ->
    finished;

increment([N|Limits], [N|Current], Done) ->
    increment(Limits, Current, [1|Done]);

increment(_Limits, [N|Current], Done) ->
    Done ++ [N+1|Current].

--------------------

1> loop:loop(fun loop:callback/1, [2,2,2,2,3]).
[1,1,1,1,1]
[2,1,1,1,1]
[1,2,1,1,1]
....



Regards,
Z.

> I was playing around with the idea of implementing a nested for-loop
> like construct (I will concede, they are evil, but at rare times,
> necessary.)  In non-functional programming languages, they are trivial
> to do.  However, this has proved to be one of those simple things that
> are a pain in the neck for me.  The idea was to be able to pass in a
> list [5, 5, 10] (for example) and go through it all like 3 dimensional
> array.  The below illustration is far from elegant (it's almost 23:00
> where I live and need to go to work tomorrow early, so no time to come
> up with something more sane :) ), but is there as an inquisitive
> exercise.  Now, in my opinion, this implementation sucks (first time
> I've ever gave such a problem a shot in Erlang.)
>
> Is there a better way to do this?  Anyone would like to demonstrate
> it?
>
> Note: I've tested this code with the lists [2, 4] and [2, 4, 5].
>
> Compiled with:
> Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.6.5
>
> My code:
> ======================================
> -module(loopWrapper).
>
> -export([runLoop/1]).
>
> runLoop(List) ->
>   [FirstVal | RestList] = List,
>   NextVal = FirstVal - 1,
>   if (length(RestList) > 0) and (FirstVal > 0) ->
>     io:format("~B~n~n", [FirstVal]),
>     runLoop(RestList),
>     io:format("~n~n"),
>     runLoop([NextVal | RestList]);
>   FirstVal > 0 ->
>     io:format("~B", [FirstVal]),
>     runLoop([NextVal]);
>   true ->
>     null
>   end.
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>




More information about the erlang-questions mailing list