Elixir队列(Erlang:queue)-枚举

时间:2018-07-26 17:55:10

标签: erlang elixir

在以下位置浏览erlang队列的文档:http://erlang.org/doc/man/queue.html#member-2 我没有办法实现Enum.Take等一系列项目。有人解决了吗?

2 个答案:

答案 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/2len/1member/2split/2