lists.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 2,008 行 · 第 1/5 页

ERL
2,008
字号
partition(Pred, L) ->    partition(Pred, L, [], []).partition(Pred, [H | T], As, Bs) ->    case Pred(H) of	true -> partition(Pred, T, [H | As], Bs);	false -> partition(Pred, T, As, [H | Bs])    end;partition(Pred, [], As, Bs) when is_function(Pred, 1) ->    {reverse(As), reverse(Bs)}.zf(F, [Hd|Tail]) ->    case F(Hd) of	true ->	    [Hd|zf(F, Tail)];	{true,Val} ->	    [Val|zf(F, Tail)];	false ->	    zf(F, Tail)    end;zf(F, []) when is_function(F, 1) -> [].foreach(F, [Hd|Tail]) ->    F(Hd),    foreach(F, Tail);foreach(F, []) when is_function(F, 1) -> ok.mapfoldl(F, Accu0, [Hd|Tail]) ->    {R,Accu1} = F(Hd, Accu0),    {Rs,Accu2} = mapfoldl(F, Accu1, Tail),    {[R|Rs],Accu2};mapfoldl(F, Accu, []) when is_function(F, 2) -> {[],Accu}.mapfoldr(F, Accu0, [Hd|Tail]) ->    {Rs,Accu1} = mapfoldr(F, Accu0, Tail),    {R,Accu2} = F(Hd, Accu1),    {[R|Rs],Accu2};mapfoldr(F, Accu, []) when is_function(F, 2) -> {[],Accu}.takewhile(Pred, [Hd|Tail]) ->    case Pred(Hd) of	true -> [Hd|takewhile(Pred, Tail)];	false -> []    end;takewhile(Pred, []) when is_function(Pred, 1) -> [].dropwhile(Pred, [Hd|Tail]=Rest) ->    case Pred(Hd) of	true -> dropwhile(Pred, Tail);	false -> Rest    end;dropwhile(Pred, []) when is_function(Pred, 1) -> [].splitwith(Pred, List) when is_function(Pred, 1) ->    splitwith(Pred, List, []).splitwith(Pred, [Hd|Tail], Taken) ->    case Pred(Hd) of	true -> splitwith(Pred, Tail, [Hd|Taken]);	false -> {reverse(Taken), [Hd|Tail]}    end;splitwith(Pred, [], Taken) when is_function(Pred, 1) ->    {reverse(Taken),[]}.split(N, List) when is_integer(N), N >= 0, is_list(List) ->    case split(N, List, []) of	{_, _} = Result -> Result;	Fault when is_atom(Fault) ->	    erlang:error(Fault, [N,List])    end;split(N, List) ->    erlang:error(badarg, [N,List]).split(0, L, R) ->    {lists:reverse(R, []), L};split(N, [H|T], R) ->    split(N-1, T, [H|R]);split(_, [], _) ->    badarg.%% Versions of the above functions with extra arguments.all(Pred, Eas, [Hd|Tail]) ->    case apply(Pred, [Hd|Eas]) of	true -> all(Pred, Eas, Tail);	false -> false    end;all(Pred, _, []) when is_function(Pred) -> true.any(Pred, Eas, [Hd|Tail]) ->    case apply(Pred, [Hd|Eas]) of	true -> true;	false -> any(Pred, Eas, Tail)    end;any(Pred, _, []) when is_function(Pred) -> false. map(F, Eas, List) -> [ apply(F, [E|Eas]) || E <- List ].flatmap(F, Eas, [Hd|Tail]) ->    apply(F, [Hd|Eas]) ++ flatmap(F, Eas, Tail);flatmap(F, _, []) when is_function(F) -> [].foldl(F, Eas, Accu, [Hd|Tail]) ->    foldl(F, Eas, apply(F, [Hd,Accu|Eas]), Tail);foldl(F, _, Accu, []) when is_function(F) -> Accu.foldr(F, Eas, Accu, [Hd|Tail]) ->    apply(F, [Hd,foldr(F, Eas, Accu, Tail)|Eas]);foldr(F, _, Accu, []) when is_function(F) -> Accu.filter(Pred, Eas, List) -> [ E || E <- List, apply(Pred, [E|Eas]) ].zf(F, Eas, [Hd|Tail]) ->    case apply(F, [Hd|Eas]) of	true ->	    [Hd|zf(F, Eas, Tail)];	{true,Val} ->	    [Val|zf(F, Eas, Tail)];	false ->	    zf(F, Eas, Tail)    end;zf(F, _, []) when is_function(F) -> [].foreach(F, Eas, [Hd|Tail]) ->    apply(F, [Hd|Eas]),    foreach(F, Eas, Tail);foreach(F, _, []) when is_function(F) -> ok.mapfoldl(F, Eas, Accu0, [Hd|Tail]) ->    {R,Accu1} = apply(F, [Hd,Accu0|Eas]),    {Rs,Accu2} = mapfoldl(F, Eas, Accu1, Tail),    {[R|Rs],Accu2};mapfoldl(F, _, Accu, []) when is_function(F) -> {[],Accu}.mapfoldr(F, Eas, Accu0, [Hd|Tail]) ->    {Rs,Accu1} = mapfoldr(F, Eas, Accu0, Tail),    {R,Accu2} = apply(F, [Hd,Accu1|Eas]),    {[R|Rs],Accu2};mapfoldr(F, _, Accu, []) when is_function(F) -> {[],Accu}.%% takewhile/2, dropwhile/2 and splitwith/2 do not have versions with%% extra arguments as this going to be discontinued.%%% =================================================================%%% Here follows the implementation of the sort functions.%%%%%% These functions used to be in their own module (lists_sort),%%% but have now been placed here to allow Dialyzer to produce better%%% type information.%%% =================================================================-compile({inline,           [{merge3_12,7}, {merge3_21,7}, {rmerge3_12,7}, {rmerge3_21,7}]}).-compile({inline,           [{umerge3_12,8}, {umerge3_21,8},	   {rumerge3_12a,7}, {rumerge3_12b,8}]}).-compile({inline,           [{keymerge3_12,12}, {keymerge3_21,12},            {rkeymerge3_12,12}, {rkeymerge3_21,12}]}).-compile({inline,          [{ukeymerge3_12,13}, {ukeymerge3_21,13},	   {rukeymerge3_12a,11}, {rukeymerge3_21a,13},	   {rukeymerge3_12b,12}, {rukeymerge3_21b,12}]}).%% sort/1%% Ascending.split_1(X, Y, [Z | L], R, Rs) when Z >= Y ->    split_1(Y, Z, L, [X | R], Rs);split_1(X, Y, [Z | L], R, Rs) when Z >= X ->    split_1(Z, Y, L, [X | R], Rs);split_1(X, Y, [Z | L], [], Rs) ->    split_1(X, Y, L, [Z], Rs);split_1(X, Y, [Z | L], R, Rs) ->    split_1_1(X, Y, L, R, Rs, Z);split_1(X, Y, [], R, Rs) ->    rmergel([[Y, X | R] | Rs], []).split_1_1(X, Y, [Z | L], R, Rs, S) when Z >= Y ->    split_1_1(Y, Z, L, [X | R], Rs, S);split_1_1(X, Y, [Z | L], R, Rs, S) when Z >= X ->    split_1_1(Z, Y, L, [X | R], Rs, S);split_1_1(X, Y, [Z | L], R, Rs, S) when S =< Z ->    split_1(S, Z, L, [], [[Y, X | R] | Rs]);split_1_1(X, Y, [Z | L], R, Rs, S) ->    split_1(Z, S, L, [], [[Y, X | R] | Rs]);split_1_1(X, Y, [], R, Rs, S) ->    rmergel([[S], [Y, X | R] | Rs], []).%% Descending.split_2(X, Y, [Z | L], R, Rs) when Z =< Y ->    split_2(Y, Z, L, [X | R], Rs);split_2(X, Y, [Z | L], R, Rs) when Z =< X ->    split_2(Z, Y, L, [X | R], Rs);split_2(X, Y, [Z | L], [], Rs) ->    split_2(X, Y, L, [Z], Rs);split_2(X, Y, [Z | L], R, Rs) ->    split_2_1(X, Y, L, R, Rs, Z);split_2(X, Y, [], R, Rs) ->    mergel([[Y, X | R] | Rs], []).split_2_1(X, Y, [Z | L], R, Rs, S) when Z =< Y ->    split_2_1(Y, Z, L, [X | R], Rs, S);split_2_1(X, Y, [Z | L], R, Rs, S) when Z =< X ->    split_2_1(Z, Y, L, [X | R], Rs, S);split_2_1(X, Y, [Z | L], R, Rs, S) when S > Z ->    split_2(S, Z, L, [], [[Y, X | R] | Rs]);split_2_1(X, Y, [Z | L], R, Rs, S) ->    split_2(Z, S, L, [], [[Y, X | R] | Rs]);split_2_1(X, Y, [], R, Rs, S) ->    mergel([[S], [Y, X | R] | Rs], []).%% merge/1mergel([[] | L], Acc) ->    mergel(L, Acc);mergel([T1, [H2 | T2], [H3 | T3] | L], Acc) ->    mergel(L, [merge3_1(T1, [], H2, T2, H3, T3) | Acc]);mergel([T1, [H2 | T2]], Acc) ->    rmergel([merge2_1(T1, H2, T2, []) | Acc], []);mergel([L], []) ->    L;mergel([L], Acc) ->    rmergel([lists:reverse(L, []) | Acc], []);mergel([], []) ->    [];mergel([], Acc) ->    rmergel(Acc, []);mergel([A, [] | L], Acc) ->    mergel([A | L], Acc);mergel([A, B, [] | L], Acc) ->    mergel([A, B | L], Acc).rmergel([[H3 | T3], [H2 | T2], T1 | L], Acc) ->    rmergel(L, [rmerge3_1(T1, [], H2, T2, H3, T3) | Acc]);rmergel([[H2 | T2], T1], Acc) ->    mergel([rmerge2_1(T1, H2, T2, []) | Acc], []);rmergel([L], Acc) ->    mergel([lists:reverse(L, []) | Acc], []);rmergel([], Acc) ->    mergel(Acc, []).%% merge3/3%% Take L1 apart.merge3_1([H1 | T1], M, H2, T2, H3, T3) when H1 =< H2 ->    merge3_12(T1, H1, H2, T2, H3, T3, M);merge3_1([H1 | T1], M, H2, T2, H3, T3) ->    merge3_21(T1, H1, H2, T2, H3, T3, M);merge3_1([], M, H2, T2, H3, T3) when H2 =< H3 ->    merge2_1(T2, H3, T3, [H2 | M]);merge3_1([], M, H2, T2, H3, T3) ->    merge2_2(T2, H3, T3, M, H2).%% Take L2 apart.merge3_2(T1, H1, M, [H2 | T2], H3, T3) when H1 =< H2 ->    merge3_12(T1, H1, H2, T2, H3, T3, M);merge3_2(T1, H1, M, [H2 | T2], H3, T3) ->    merge3_21(T1, H1, H2, T2, H3, T3, M);merge3_2(T1, H1, M, [], H3, T3) when H1 =< H3 ->    merge2_1(T1, H3, T3, [H1 | M]);merge3_2(T1, H1, M, [], H3, T3) ->    merge2_2(T1, H3, T3, M, H1).% H1 =< H2. Inlined.merge3_12(T1, H1, H2, T2, H3, T3, M) when H1 =< H3 ->    merge3_1(T1, [H1 | M], H2, T2, H3, T3);merge3_12(T1, H1, H2, T2, H3, T3, M) ->    merge3_12_3(T1, H1, H2, T2, [H3 | M], T3).% H1 =< H2, take L3 apart.merge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) when H1 =< H3 ->    merge3_1(T1, [H1 | M], H2, T2, H3, T3);merge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) ->    merge3_12_3(T1, H1, H2, T2, [H3 | M], T3);merge3_12_3(T1, H1, H2, T2, M, []) ->    merge2_1(T1, H2, T2, [H1 | M]).% H1 > H2. Inlined.merge3_21(T1, H1, H2, T2, H3, T3, M) when H2 =< H3 ->    merge3_2(T1, H1, [H2 | M], T2, H3, T3);merge3_21(T1, H1, H2, T2, H3, T3, M) ->    merge3_21_3(T1, H1, H2, T2, [H3 | M], T3).% H1 > H2, take L3 apart.merge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) when H2 =< H3 ->    merge3_2(T1, H1, [H2 | M], T2, H3, T3);merge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) ->    merge3_21_3(T1, H1, H2, T2, [H3 | M], T3);merge3_21_3(T1, H1, H2, T2, M, []) ->    merge2_2(T1, H2, T2, M, H1).%% rmerge/3%% Take L1 apart.rmerge3_1([H1 | T1], M, H2, T2, H3, T3) when H1 =< H2 ->    rmerge3_12(T1, H1, H2, T2, H3, T3, M);rmerge3_1([H1 | T1], M, H2, T2, H3, T3) ->    rmerge3_21(T1, H1, H2, T2, H3, T3, M);rmerge3_1([], M, H2, T2, H3, T3) when H2 =< H3 ->    rmerge2_2(T2, H3, T3, M, H2);rmerge3_1([], M, H2, T2, H3, T3) ->    rmerge2_1(T2, H3, T3, [H2 | M]).%% Take L2 apart.rmerge3_2(T1, H1, M, [H2 | T2], H3, T3) when H1 =< H2 ->    rmerge3_12(T1, H1, H2, T2, H3, T3, M);rmerge3_2(T1, H1, M, [H2 | T2], H3, T3) ->    rmerge3_21(T1, H1, H2, T2, H3, T3, M);rmerge3_2(T1, H1, M, [], H3, T3) when H1 =< H3 ->    rmerge2_2(T1, H3, T3, M, H1);rmerge3_2(T1, H1, M, [], H3, T3) ->    rmerge2_1(T1, H3, T3, [H1 | M]).% H1 =< H2. Inlined.rmerge3_12(T1, H1, H2, T2, H3, T3, M) when H2 =< H3 ->    rmerge3_12_3(T1, H1, H2, T2, [H3 | M], T3);rmerge3_12(T1, H1, H2, T2, H3, T3, M) ->    rmerge3_2(T1, H1, [H2 | M], T2, H3, T3).% H1 =< H2, take L3 apart.rmerge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) when H2 =< H3 ->    rmerge3_12_3(T1, H1, H2, T2, [H3 | M], T3);rmerge3_12_3(T1, H1, H2, T2, M, [H3 | T3]) ->    rmerge3_2(T1, H1, [H2 | M], T2, H3, T3);rmerge3_12_3(T1, H1, H2, T2, M, []) ->    rmerge2_2(T1, H2, T2, M, H1).% H1 > H2. Inlined.rmerge3_21(T1, H1, H2, T2, H3, T3, M) when H1 =< H3 ->    rmerge3_21_3(T1, H1, H2, T2, [H3 | M], T3);rmerge3_21(T1, H1, H2, T2, H3, T3, M) ->    rmerge3_1(T1, [H1 | M], H2, T2, H3, T3).% H1 > H2, take L3 apart.rmerge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) when H1 =< H3 ->    rmerge3_21_3(T1, H1, H2, T2, [H3 | M], T3);rmerge3_21_3(T1, H1, H2, T2, M, [H3 | T3]) ->    rmerge3_1(T1, [H1 | M], H2, T2, H3, T3);rmerge3_21_3(T1, H1, H2, T2, M, []) ->    rmerge2_1(T1, H2, T2, [H1 | M]).%% merge/2merge2_1([H1 | T1], H2, T2, M) when H1 =< H2 ->    merge2_1(T1, H2, T2, [H1 | M]);merge2_1([H1 | T1], H2, T2, M) ->    merge2_2(T1, H2, T2, M, H1);merge2_1([], H2, T2, M) ->    lists:reverse(T2, [H2 | M]).merge2_2(T1, HdM, [H2 | T2], M, H1) when H1 =< H2 ->    merge2_1(T1, H2, T2, [H1, HdM | M]);merge2_2(T1, HdM, [H2 | T2], M, H1) ->    merge2_2(T1, H2, T2, [HdM | M], H1);merge2_2(T1, HdM, [], M, H1) ->    lists:reverse(T1, [H1, HdM | M]).%% rmerge/2rmerge2_1([H1 | T1], H2, T2, M) when H1 =< H2 ->    rmerge2_2(T1, H2, T2, M, H1);rmerge2_1([H1 | T1], H2, T2, M) ->    rmerge2_1(T1, H2, T2, [H1 | M]);rmerge2_1([], H2, T2, M) ->    lists:reverse(T2, [H2 | M]).rmerge2_2(T1, HdM, [H2 | T2], M, H1) when H1 =< H2 ->    rmerge2_2(T1, H2, T2, [HdM | M], H1);rmerge2_2(T1, HdM, [H2 | T2], M, H1) ->    rmerge2_1(T1, H2, T2, [H1, HdM | M]);rmerge2_2(T1, HdM, [], M, H1) ->    lists:reverse(T1, [H1, HdM | M]).%% usort/1%% Ascending.usplit_1(X, Y, [Z | L], R, Rs) when Z > Y ->    usplit_1(Y, Z, L, [X | R], Rs);usplit_1(X, Y, [Z | L], R, Rs) when Z == Y ->    usplit_1(X, Y, L, R, Rs);usplit_1(X, Y, [Z | L], R, Rs) when Z > X ->    usplit_1(Z, Y, L, [X | R], Rs);usplit_1(X, Y, [Z | L], R, Rs) when Z == X ->    usplit_1(X, Y, L, R, Rs);usplit_1(X, Y, [Z | L], [], Rs) ->    usplit_1(X, Y, L, [Z], Rs);usplit_1(X, Y, [Z | L], R, Rs) ->    usplit_1_1(X, Y, L, R, Rs, Z);usplit_1(X, Y, [], R, Rs) ->    rumergel([[Y, X | R] | Rs], [], asc).usplit_1_1(X, Y, [Z | L], R, Rs, S) when Z > Y ->    usplit_1_1(Y, Z, L, [X | R], Rs, S);usplit_1_1(X, Y, [Z | L], R, Rs, S) when Z == Y ->    usplit_1_1(X, Y, L, R, Rs, S);usplit_1_1(X, Y, [Z | L], R, Rs, S) when Z > X ->    usplit_1_1(Z, Y, L, [X | R], Rs, S);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?