【问题标题】:returning nothing from a list comprehension从列表理解中不返回任何内容
【发布时间】:2018-05-11 00:31:05
【问题描述】:

假设您有以下列表理解:

for i <- 2..n |> Enum.map(&(&1*&1+ &1), i <= :math.sqrt(n), do
  Refrigerator.put(pid, i, "this is my food")
end

有没有一种惯用的方法来禁止返回结果理解?

对于这样的情况,我对返回的理解不感兴趣,但是 for 使得生成副作用函数所需的参数变得非常容易。

【问题讨论】:

标签: for-loop elixir list-comprehension return-value side-effects


【解决方案1】:

我不能说这是多么地道,但如果您担心效率,您总是可以创建一个实现 Collectable 但实际上不做任何工作的结构。

defmodule NoCollect do
  defstruct []
end

defimpl Collectable, for: NoCollect do
  def into(pool) do
    {pool, fn
      expr, {:cont, _} -> expr
      expr, :done -> expr
      _   , :halt -> :ok
    end}
  end
end

那你就可以这样使用了

for ..., into: %NoCollect{} do
  # ...
end

从技术上讲,您仍然会得到一个理解对象,但现在它将是一个微不足道的 %NoCollect{} 对象,无论循环运行多少次,而不是实际累积然后丢弃值。

【讨论】:

  • 谢谢你——感谢n,这使得机器内存不足或高效执行具有副作用的理解之间有所不同。
  • 我认为更好的问题是为什么有人只想对副作用进行理解。似乎最好使用 map 或 reduce 或该系列中的其他函数来处理它。
【解决方案2】:

如果这是关于为大的n 建立回报的内存消耗,我想你也想避免Enum.map 而不是2..n

您是否尝试过使用 Streams?

2..n
|> Stream.map(& &1*&1 + &1)
|> Stream.filter(& &1 <= :math.sqrt(n))
|> Enum.each(& Refrigerator.put(pid, &1, "this is my food"))

【讨论】:

  • 谢谢,现在我看到这里迭代的关键是Enum.each
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
相关资源
最近更新 更多