在以下位置浏览erlang队列的文档:http://erlang.org/doc/man/queue.html#member-2 我没有办法实现Enum.Take等一系列项目。有人解决了吗?
答案 0 :(得分:2)
Erlang为尽可能使用递归而不是命令式调用而感到自豪。所需的行为可能很容易实现:
def take(q, amount), do: do_take(q, {amount, []})
defp do_take(q, {n, acc}) when n > 0 do
case :queue.out(q) do
{{:value, e}, rest} ->
do_take(rest, {n - 1, [e | acc]})
{:empty, q} -> {acc, q}
end
end
defp do_take(q, {_, acc}), do: {acc, q}
我还没有测试过这段代码,但是我相信这个主意很清楚。
或者,用一种奇妙的else
语法:
def take(q, amount), do: do_take(q, {amount, []})
defp do_take(q, {n, acc}) when n > 0 do
:queue.out(q)
else
{{:value, e}, rest} -> do_take(rest, {n - 1, [e | acc]})
{:empty, q} -> {acc, q}
end
defp do_take(q, {_, acc}), do: {acc, q}
答案 1 :(得分:1)
我没有办法提取Enum.Take之类的项目。已 有人解决了吗?
是的。在您链接的页面上:
split(N :: integer() >= 0, Q1 :: queue(Item)) -> {Q2 :: queue(Item), Q3 :: queue(Item)}
将Q1一分为二。 N个前项放在Q2中,其余的放在Q3中。
因此,您可以这样做:
-module(my).
-compile(export_all).
take(N, Q) ->
{Taken, _Rest} = queue:split(N, Q),
Taken.
在外壳中:
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> Q = queue:from_list([1,2,3,4]).
{[4],[1,2,3]}
3> T1 = my:take(1, Q).
{[],[1]}
4> queue:to_list(T1).
[1]
5> T3 = my:take(3, Q).
{[3],[1,2]}
6> queue:to_list(T3).
[1,2,3]
除
filter/2
之外的所有操作都具有摊销的O(1)运行时间, 具有O(n)的join/2
,len/1
,member/2
,split/2
。