在Erlang中实现partition_by函数

时间:2014-03-26 18:12:53

标签: algorithm erlang

我试图在Erlang中创建一个分区依据函数,其中第一个参数是谓词函数。

step(_, [ ]) ->
  [ ];

step(N, C) ->
  [_ | T] = C,
  case (N > 0) and (length(C) > 0) of
    true ->
      step(N - 1, T);
    false ->
      C
  end.

drop(_, [ ]) ->
  [ ];

drop(Number, Collection) ->
  step(Number, Collection).

partition_by(_, [ ]) ->
  [ ];

partition_by(F, Collection) ->
  [H | T] = [Collection],
  Head_value = F(H),
  Run = [H | lists:takewhile(fun(E) -> Head_value =:= F(E) end, T)],
  [Run | partition_by(F, erl_funcs:drop(length(Run), Collection))].

但是在打电话时:

partition_by(fun(E) -> E > 0 end, [-44444, -4555555, 455555]).

我得到了:

[[[-44444,-4555555,455555]],[[-4555555,455555]],[[455555]]]

不完全是我想到的。出了什么问题?

2 个答案:

答案 0 :(得分:1)

当你没有提供所需的输出时,我不知道它应该如何工作,但我会猜测。

partition_by(F, [H|T]) ->
  partition_by(F, F(H), T, [H]).

partition_by(F, HV, [H|T] = L, Acc) ->
  case F(H) of
    HV -> partition_by(F, HV, T, [H|Acc]);
    _ -> {lists:reverse(Acc), L}
  end;
partition_by(_, _, [], Acc) -> {lists:reverse(Acc), []}. 

答案 1 :(得分:1)

此行[H | T] = [Collection],在您的代码中有误。 我将其更改为[H | T] = Collection,

我认为您希望从列表Collection中获取一个元素,因此您需要[H | T] = Collection。 如果您使用[H | T] = [Collection],则表示H = Collection, T = []

这是我的完整代码。

-module(wy).
-compile(export_all).

drop(_, []) ->
     [];
drop(0, Collection) ->
    Collection;
drop(Number, [_H | T]) ->
    drop(Number - 1, T).

partition_by(_, [ ]) ->
  [ ];

partition_by(F, Collection) ->
  [H | T] = Collection,
  Head_value = F(H),
  Run = [H | lists:takewhile(fun(E) -> Head_value =:= F(E) end, T)],
  [Run | partition_by(F, ?MODULE:drop(length(Run), Collection))].

main() ->
    T = partition_by(fun(E) -> E > 0 end, [-44444, -4555555, 455555]),
    io:format("~w~n", [T]).

输出为:[[-44444,-4555555],[455555]]