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 + -
显示快捷键?