Erlang - 元素和列表

4

我是一个新手,想知道如何编写一个函数来返回列表中的前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...)

有什么提示吗?谢谢。

更新:我知道有一个名为“sublist”的函数,但我需要自己编写该函数。

我最终找到了答案:

-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.
2个回答

28

在Erlang中,take的意思可以用lists:sublist来表示:

L = [1, 2, 3, 4];
lists:sublist(L, 3).   % -> [1, 2, 3]

8
一个简单的解决方案是:
take([H|T], N) when N > 0 ->
    [H|take(T, N-1)];
take(_, 0) -> [].

如果列表中的元素不足,则会生成错误。

当您使用累加器时,通常不会将元素附加到其末尾,因为这样非常低效(每次都要复制整个列表)。您通常会使用[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).

累加器版本是尾递归,这是一件好事情,但你需要做一个额外的反转,这将减少一些优势。我认为第一版更清晰。两种方法都没有明显的区别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接