从Enum.each循环中将字符串插入队列

时间:2016-12-27 00:03:16

标签: enums elixir

jekyll serve --watch

也许我做的事情比他们需要的更复杂。我有一个字符串列表("种子"),我想将其设置到队列中。

我已经读过在每个循环中设置的变量都没有保存,那么我该如何实现呢?

对于每个字符串def process({:page_link, url}, queue) do IO.puts "Downloading page: #{url}" torrents = download(url) |> torrent_links Enum.each(torrents, fn(torrent) -> IO.puts "Adding torrent to queue: #{torrent}" queue = :queue.in({:torrent_link, torrent}, queue) IO.inspect queue end) queue end ,将其设置为队列并返回新队列。

3 个答案:

答案 0 :(得分:1)

您正在寻找 onkeypress="return (event.which >= 48 && event.which <= 57) || event.which == 8 || event.keyCode == 46 || event.keyCode == 37 || event.keyCode == 39" maxlength="12"

Enum.reduce/3

由于def process({:page_link, url}, queue) do IO.puts "Downloading page: #{url}" torrents = download(url) |> torrent_links Enum.reduce(torrents, queue, fn(torrent, queue) -> IO.puts "Adding torrent to queue: #{torrent}" IO.inspect :queue.in({:torrent_link, torrent}, queue) end) end 在打印后返回值,我还合并了IO.inspect/1queue =行。

答案 1 :(得分:1)

首先,将torrent链接转换为队列中所需的内容:

queue_elems = Enum.map(torrents, fn(t) -> {:torrent_link, torrent}

如果有,您可以将该列表提供给Enum.reduce,并将队列作为累加器:

Enum.reduce(queue_elems, queue, fn(e, q) -> :queue.in(e, q))

这将遍历要插入的元素,队列为&#34; accumulator&#34; - :queue.in的返回值在下一次调用时用作累加器的新值,逐渐将元素列表推送到单个事物中(因此&#34;减少&#34;)。毋庸置疑,两个片段都可以组合在一个管道中,甚至可以转换为一个步骤,但我常常发现在处理性能时需要将各个处理步骤分开。

你的代码不起作用的原因是循环中的变量与循环外的变量不同。每http://elixir-lang.readthedocs.io/en/latest/technical/scoping.html#scope-nesting-and-shadowing

  

嵌套作用域中的任何变量,其名称与周围作用域中的变量一致,将遮蔽该外部变量。换句话说,嵌套作用域内的变量暂时隐藏了周围作用域中的变量,但不会以任何方式影响它。

所以即使他们有相同的名字,他们也是不同的东西。在学习Elixir时,您需要掌握一些东西,但通常使用更惯用的方法(比如不使用Enum.each手动循环,而是将数据提供给更高级别的函数,如{{1} },filtermap等等,您可以完全避免在这方面存在问题的代码。

(对于这个特殊问题,有一个更简单的解决方案:reduce将创建一个新队列,然后可以使用:queue.from_list(queue_elems)将函数参数中的队列与生成的队列连接起来)。

答案 2 :(得分:1)

Enum.reduce/3中没有必要。 :queue.from_list/1:queue.join/2可以解决问题:

def process({:page_link, url}, queue) do
  url
  |> download
  |> torrent_links
  |> Enum.map(& {:torrent_link, &1})
  |> :queue.from_list
  |> :queue.join(queue)
end