Nested for-loops, there has to be a better way to do this
Andy Kilroy
lemonkandy@REDACTED
Thu Jul 30 02:25:18 CEST 2009
> Is there a better way to do this? Anyone would like to demonstrate
> it?
Recommend you learn about the lists:foldl and lists:foldr functions.
Whenever
I'm about to perform iterations over lists I always think of using
these. It
means that all you have to do is think 'What action do I want to
perform in
each iterative step?'; supply this as the function parameter to foldl
(or
foldr, whichever's appropriate).
> 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.
Hmm, I could only figure out what you wanted to do by running your
program.
I've coded a solution below, but bear in mind I've redefined your
problem
somewhat, to keep the solution fairly generic. Instead of printing to
the
terminal, I've stated that the loop must return a result.
----------------
-module(looper).
-export([loop/3, nestedLooping/3]).
loop(Acc, SideEffect, IntList) ->
Exploded = explodeElements(IntList),
nestedLooping(Acc, SideEffect, Exploded).
nestedLooping(Acc, _SideEffect, []) -> Acc;
nestedLooping(Acc, SideEffect, [InnerList | TheRest]) ->
Func = fun(Elem, Accum) ->
SideEffect(Elem, nestedLooping(Accum, SideEffect, TheRest))
end,
lists:foldl(Func, Acc, InnerList).
explodeElements([]) ->
[];
explodeElements([X | IntList]) ->
[lists:seq(1, X) | explodeElements(IntList)].
----------------
The clever work's done in the nestedLooping function.
Tests are below, showing you how I use the loop definition above. I've
tried to
format the output list so that it's bit easier to spot how it
corresponds with
the output from your program.
----------------
empty_int_list_does_nothing(_Config) ->
[] = looper:loop([], fun my_callback/2, []).
two_dimen_iteration(_Config) ->
[2, 4, 3, 2, 1,
1, 4, 3, 2, 1] =
looper:loop([], fun my_callback/2, [2, 4]).
three_dimen_iteration(_Config) ->
[2, 4, 5, 4, 3, 2, 1,
3, 5, 4, 3, 2, 1,
2, 5, 4, 3, 2, 1,
1, 5, 4, 3, 2, 1,
1, 4, 5, 4, 3, 2, 1,
3, 5, 4, 3, 2, 1,
2, 5, 4, 3, 2, 1,
1, 5, 4, 3, 2, 1 ] =
looper:loop([], fun my_callback/2, [2, 4, 5]).
my_callback(Element, Accumulator) ->
[Element | Accumulator].
----------------
Hope that's helpful,
Andy
More information about the erlang-questions
mailing list