Erlang - 元素和列表

Fer*_*rry 4 erlang list

我是二郎的新手.我想知道如何编写一个返回列表中前N个元素的函数?

我试过了:

    take([],_) -> [];
    take([H|T],N) when N > 0 -> take([H,hd(L)|tl(T)], N-1);
    take([H|T],N) when N == 0 -> ... (I'm stuck here...)
Run Code Online (Sandbox Code Playgroud)

任何提示?谢谢

更新:我知道有一个名为"子列表"的函数,但我需要弄清楚如何自己编写该函数.

我终于找到了答案:

-module(list).
-export([take/2]).

take(List,N) -> take(List,N,[]).
take([],_,[]) -> [];
take([],_,List) -> List;
take([H|T], N, List) when N > 0 -> take(T, N-1, lists:append(List,[H]));
take([H|T], N, List) when N == 0 -> List.
Run Code Online (Sandbox Code Playgroud)

War*_*ung 25

在Erlang take中拼写lists:sublist:

L = [1, 2, 3, 4];
lists:sublist(L, 3).   % -> [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)


rvi*_*ing 8

一个简单的解决方案是

take([H|T], N) when N > 0 ->
    [H|take(T, N-1)];
take(_, 0) -> [].
Run Code Online (Sandbox Code Playgroud)

如果列表中没有足够的元素,这将生成错误.

当你正在使用累加器时,通常不会将元素附加到它的末尾,因为这是非常低效的(每次都复制整个列表).你通常会把元素推到它上面[H|List].然后它将以相反的顺序,但你然后做一个lists:reverse(List)以正确的顺序返回它们.

take(List, N) -> take(List, N, []).

take([H|T], N, Acc) when N > 0 ->
    take(T, N-1, [H|Acc]);
take(_, 0, Acc) -> lists:reverse(Acc).
Run Code Online (Sandbox Code Playgroud)

累加器版本是尾递归,这是一个很好的事情,但你需要做一个额外的反向,这消除了一些好处.我认为第一个版本更清晰.两者都没有明确的案例.