list handling functions
Vladimir Sekissov
svg@REDACTED
Fri Sep 19 11:56:55 CEST 2003
Good day,
In the attachment is my library module for list of lists processing.
In your case it will be applyn:
8> wslib.listn:applyn(fun (A, B, C) -> A+B+C end,[[1,2,3], [4,5,6], [7,8,9]]).
[12,15,18]
Best Regards,
Vladimir Sekissov
vlad_dumitrescu> Hi,
vlad_dumitrescu>
vlad_dumitrescu> Maybe tomorrow I will be ashamed to have asked a question whose answer is
vlad_dumitrescu> obvious, but here it goes:
vlad_dumitrescu>
vlad_dumitrescu> Are there any ways to simply express a 'map' (or similar) function that
vlad_dumitrescu> iterates over several lists at once? I use something like
vlad_dumitrescu>
vlad_dumitrescu> map2(Fun, A, B) ->
vlad_dumitrescu> map2(Fun, A, B, []).
vlad_dumitrescu>
vlad_dumitrescu> map2(Fun, [], _, Res) ->
vlad_dumitrescu> lists:reverse(Res);
vlad_dumitrescu> map2(Fun, _, [], Res) ->
vlad_dumitrescu> lists:reverse(Res);
vlad_dumitrescu> map2(Fun, [Ha|Ta],[Hb|Tb],Res)->
vlad_dumitrescu> map2(Fun, Ta, Tb, [Fun(Ha, Hb)|Res]).
vlad_dumitrescu>
vlad_dumitrescu> but this seems to be general enough to be found in a library. Or maybe list
vlad_dumitrescu> comprehensions could be used in a clever way?
vlad_dumitrescu>
vlad_dumitrescu> thanks in advance,
vlad_dumitrescu> Vlad
-------------- next part --------------
%%%----------------------------------------------------------------------
%%% File : listn.erl
%%% Author : <svg@REDACTED>
%%% Purpose :
%%% Created : 12 Oct 2001 by <svg@REDACTED>
%%%----------------------------------------------------------------------
-module(wslib.listn).
-vsn('$Id\$').
-author('svg@REDACTED').
-export([listn/1, appendn/1, applyn/2, zip/2, zipn/1, unzip/1, unzipn/1]).
-export([foldn/3, mapn/2]).
-export([mk_list/1, split_on/2, split/2]).
-import(.lists).
%%
%% listn([[1,2,3], [4,5,6], [7,8,9]]) ->[[1,4,7],[2,5,8],[3,6,9]]
%%
listn(Ls) ->
[lists:reverse(L)
|| L <- foldn(fun (A, Acc) -> [A|Acc] end, [], Ls)].
%%
%% appendn([[[1,2,3], [4,5,6], [7,8,9]], [[a,b,c], [d,e,f], [g, h, i]]]) ->
%% [[1,2,3,a,b,c],[4,5,6,d,e,f],[7,8,9,g,h,i]]
%%
appendn(L) ->
foldn(fun (A, Acc) -> Acc ++ A end, [], L).
%%
%% applyn(fun (A, B, C) -> A+B+C end, [[1,2,3], [4,5,6], [7,8,9]]) ->
%% [12,15,18]
%%
applyn(Fun, LL) ->
[apply(Fun, L) || L <- listn(LL)].
foldn(_, _, []) ->
[];
foldn(Fun, Acc0, Ls) ->
foldn(Fun, Acc0, Ls, []).
foldn(_, _, [[]|_], Ret) ->
lists:reverse(Ret);
foldn(Fun, Acc0, Ls, Ret) ->
foldn(Fun, Acc0,
[tl(L) || L <- Ls],
[lists:foldl(Fun, Acc0, [hd(L) || L <- Ls])|Ret]
).
%%
%% mapn(fun (A, B, C) -> A+B+C end, [[1,2,3], [4,5,6], [7,8,9]]) ->
%% [[[12,13,14],[13,14,15],[14,15,16]],
%% [[13,14,15],[14,15,16],[15,16,17]],
%% [[14,15,16],[15,16,17],[16,17,18]]]
%%
mapn(Fun, []) ->
[];
mapn(Fun, List) when list(List) ->
mapn(Fun, List, []).
mapn(Fun, [List], Args) ->
lists:map(fun (E) -> apply(Fun, lists:reverse([E|Args])) end, List);
mapn(Fun, [List|Rest], Args) ->
lists:map(fun (E) -> mapn(Fun, Rest, [E|Args]) end, List).
zip(L1, L2) ->
zip(L1, L2, []).
zip(L1, L2, Res) when L1 == []; L2 == [] ->
lists:reverse(Res);
zip([E1|Rest1], [E2|Rest2], Acc) ->
zip(Rest1, Rest2, [{E1, E2}|Acc]).
zipn(List) ->
[list_to_tuple(L) || L <- listn(List)].
unzip(List) ->
{L1, L2} =
lists:foldl(fun ({E1, E2}, {Es1, Es2}) ->
{[E1|Es1], [E2|Es2]}
end, {[], []}, List),
{lists:reverse(L1), lists:reverse(L2)}.
unzipn(List) ->
listn([tuple_to_list(T) || T <- List]).
mk_list(V) when list(V) ->
V;
mk_list(V) ->
[V].
split_on(Pos, L) when is_integer(Pos), Pos >= 0 ->
split_on(Pos, L, []).
split_on(0, Tail, Head) ->
{lists:reverse(Head), Tail};
split_on(Num, [E|Rest], Acc) ->
split_on(Num-1, Rest, [E|Acc]).
split(Size, L) ->
split(Size, L, []).
split(Size, L, Acc) when length(L) =< Size ->
lists:reverse([L|Acc]);
split(Size, L, Acc) ->
{H, T} = split_on(Size, L),
split(Size, T, [H|Acc]).
More information about the erlang-questions
mailing list