从列表理解中返回任何内容
returning nothing from a list comprehension
假设您有以下列表理解:
for i <- 2..n |> Enum.map(&(&1*&1+ &1), i <= :math.sqrt(n), do
Refrigerator.put(pid, i, "this is my food")
end
是否有一种惯用的方法来禁用结果理解的返回?
对于这种情况,我对返回的理解不感兴趣,但是 for
使得生成副作用函数所需的参数变得非常容易。
我不能说这是多么地道,但如果您担心效率,您总是可以创建一个实现 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
构建 return 的内存消耗,我想您会希望避免 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"))
假设您有以下列表理解:
for i <- 2..n |> Enum.map(&(&1*&1+ &1), i <= :math.sqrt(n), do
Refrigerator.put(pid, i, "this is my food")
end
是否有一种惯用的方法来禁用结果理解的返回?
对于这种情况,我对返回的理解不感兴趣,但是 for
使得生成副作用函数所需的参数变得非常容易。
我不能说这是多么地道,但如果您担心效率,您总是可以创建一个实现 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
构建 return 的内存消耗,我想您会希望避免 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"))