FunProd = fun(Product) ->
FunDay = fun(Date) ->
print_sales([Product, Date])
end,
lists:foreach(FunDay, get_current_week())
end,
lists:foreach(FunProd, get_product_list()). |
loop_lists function should behave as follows:
1> loop_lists([[spanner, screwdriver],[monday,tuesday,wednesday]]). [[spanner,monday], [spanner,tuesday], [spanner,wednesday], [screwdriver,monday], [screwdriver,tuesday], [screwdriver,wednesday]] |
2> loop_lists([[a,b],[x,y],[1,2,3]]). [[a,x,1], [a,x,2], [a,x,3], [a,y,1], [a,y,2], [a,y,3], [b,x,1], [b,x,2], [b,x,3], [b,y,1], [b,y,2], [b,y,3]] |
> lists:map(MyFunction, loop_lists([ProductList,DayList])). > [MyFunction(ProdDay) || ProdDay <- loop_lists([ProductList,DayList])]. |
loop_lists([]) -> [[]]; loop_lists([H|[]]) -> [[X] || X <- H]; loop_lists([H|T]) -> [[X|Y] || X <- H, Y <- loop_lists(T)]. |
loop_lists(L) -> loop_lists(L, []). loop_lists([], Acc) -> Acc; loop_lists([H|T], []) -> loop_lists(T, [[X] || X <- H]); loop_lists([H|T], Acc) -> loop_lists(T, [lists:append(X, [Y]) || X <- Acc, Y <- H]). |
lists:append, which may have a significant performance impact with larger lists.
loop_lists(L) -> loop_lists(lists:reverse(L), []). loop_lists([], Acc) -> Acc; loop_lists([H|T], []) -> loop_lists(T, [[X] || X <- H]); loop_lists([H|T], Acc) -> loop_lists(T, [[X|Y] || X <- H, Y <- Acc]). |
lists:append. It does use lists:reverse once on the initial source list so that the target lists are accumulated in the correct order.
This version is probably the best of attempts 1-3, but still requires the same amount of memory to hold the resulting looping list.
map, foreach (etc) functions from the lists module to each source list, passing the remaining source lists and the accumulated argument list through to each call.
loop_lists(Fun, Lists) -> loop_lists(foreach, Fun, Lists, []). % Use foreach by default.
loop_lists(Method, Fun, Lists) -> loop_lists(Method, Fun, Lists, []). % User-selected list function.
loop_lists(_Method, Fun, [], Args) -> Fun(Args);
loop_lists(Method, Fun, [H|T], Args) ->
FunLoop = fun(Elem) -> loop_lists(Method, Fun, T, Args ++ [Elem]) end,
apply(lists, Method, [FunLoop, H]).
1> loop_lists(fun(X) -> io:format("~w~n", [X]) end, [[a,b,c],[x,y],[1,2]]).
[a,x,1]
[a,x,2]
[a,y,1]
[a,y,2]
[b,x,1]
[b,x,2]
[b,y,1]
[b,y,2]
[c,x,1]
[c,x,2]
[c,y,1]
[c,y,2]
ok |
lists:map, lists:foreach, etc).
Solution 2 does seem to be a bit more readable than the Solution 1 attempts, but that is probably only my inexperience with list comprehensions.
I have yet to actually analyse and compare these pieces of code for performance, memory usage, etc.
% Using Nested Functions:
Fun1 = fun(Elem1) ->
Fun2 = fun(Elem2) ->
Fun3 = fun(Elem3) ->
do_something([Elem1, Elem2, Elem3])
end,
lists:foreach(Fun3, List3)
end,
lists:foreach(Fun2, List2)
end,
lists:foreach(Fun1, List1).
% Solution 1:
lists:foreach(
fun(X) ->
do_something(X)
end,
loop_lists([List1, List2, List3])).
% Solution 2:
loop_lists(
fun(X) ->
do_something(X)
end,
[List1, List2, List3]). |
| CookbookForm | |
|---|---|
| TopicType: | Recipe |
| ParentTopic: | ListRecipes |
| TopicOrder: | 090 |