list handling functions

Vladimir Sekissov <>
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  :  <>
%%% Purpose : 
%%% Created : 12 Oct 2001 by  <>
%%%----------------------------------------------------------------------

-module(wslib.listn).
-vsn('$Id\$').
-author('').

-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