Enums 从Enum.each循环中将字符串插入队列
也许我做的事情比他们需要的更复杂。我有一个字符串列表(“torrents”),我想将其设置到队列中 我已经读到在Each循环中设置的变量不会被保存,那么我如何才能做到这一点呢Enums 从Enum.each循环中将字符串插入队列,enums,elixir,Enums,Elixir,也许我做的事情比他们需要的更复杂。我有一个字符串列表(“torrents”),我想将其设置到队列中 我已经读到在Each循环中设置的变量不会被保存,那么我如何才能做到这一点呢 对于每个字符串torrent将其设置到队列中并返回新队列。您正在查找Enum.reduce/3: def process({:page_link, url}, queue) do IO.puts "Downloading page: #{url}" torrents = download(url) |> to
对于每个字符串
torrent
将其设置到队列中并返回新队列。您正在查找Enum.reduce/3
:
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
由于
IO.inspect/1
在打印后返回值,因此我还合并了queue=
和IO.inspect
行。首先,将torrent链接转换为队列中需要的内容:
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
当您拥有该列表时,您可以将该列表馈送到Enum.reduce
,队列作为累加器:
queue_elems = Enum.map(torrents, fn(t) -> {:torrent_link, torrent}
这将循环您要插入的元素,队列作为“累加器”——:queue的返回值。
在下一次调用中用作累加器的新值,逐渐将元素列表推到单个对象中(因此“减少”)。不用说,这两个代码段都可以组合在管道中,甚至可以转换为单个步骤,但我经常发现,在关注性能之前,将各个处理步骤分开比较容易
代码无法工作的原因是循环中的变量与循环外的变量不同。Per:
嵌套作用域中的任何变量,如果其名称与周围作用域中的变量一致,则该外部变量将被隐藏。换句话说,嵌套范围内的变量会临时隐藏周围范围内的变量,但不会以任何方式影响它
因此,尽管它们有相同的名字,但它们是不同的东西。在学习长生不老药时,你需要绞尽脑汁,但通常要使用更惯用的方法(比如不要手动循环使用Enum.each
,而是将数据提供给更高级别的函数,如filter
,map
,reduce
,等等)您可以完全避免在这方面有问题的代码
(对于这个特定的问题,有一个更简单的解决方案::queue.from_list(queue_elems)
将创建一个新队列,然后可以使用:queue.join
将函数参数中的队列与生成的队列联接起来)。不需要。这样做的诀窍是:
Enum.reduce(queue_elems, queue, fn(e, q) -> :queue.in(e, q))
def process({:page_link, url}, queue) do
url
|> download
|> torrent_links
|> Enum.map(& {:torrent_link, &1})
|> :queue.from_list
|> :queue.join(queue)
end