有条件地从Stream中获取元素

时间:2017-12-02 20:37:57

标签: stream conditional elixir take

我已经实现了以下功能:

  def gaussian(center, height, width) do
    Stream.iterate(1, &(&1 + 1))
    |> Stream.map(fn (x) -> x - center end)
    |> Stream.map(fn (x) -> :math.pow(x, 2) end)
    |> Stream.map(fn (x) -> -x / (2 * :math.pow(width, 2))  end)
    |> Stream.map(fn (x) -> height * :math.exp(x) end)
    |> Stream.map(&Kernel.round/1)
    |> Stream.take_while(&(&1 > 0))
    |> Enum.to_list                                                            
  end

使用给定的args,返回一个空列表:

iex> gaussian(10, 10, 3)
[]

删除Stream.take_while/2

  def gaussian(center, height, width) do
    Stream.iterate(1, &(&1 + 1))
    |> Stream.map(fn (x) -> x - center end)
    |> Stream.map(fn (x) -> :math.pow(x, 2) end)
    |> Stream.map(fn (x) -> -x / (2 * :math.pow(width, 2))  end)
    |> Stream.map(fn (x) -> height * :math.exp(x) end)
    |> Stream.map(&Kernel.round/1)
    #|> Stream.take_while(&(&1 > 0))                                                   
    #|> Enum.to_list                                                                   
    |> Enum.take(20)
  end
然而

给出了这个:

iex> gaussian(10, 10, 3)
[0, 0, 1, 1, 2, 4, 6, 8, 9, 10, 9, 8, 6, 4, 2, 1, 1, 0, 0, 0]

我的Stream.take_while/2电话是否有问题,或者我在这里完全错过了什么?

1 个答案:

答案 0 :(得分:2)

Stream.take_while/2停止对第一次评估为false的函数进行评估。

在您的情况下,您的功能在:

|> Stream.take_while(&(&1 > 0))

使用指定的参数,如

gaussian(10, 10, 3)

在第一次迭代中会收到0,因此当您的表达式&1 > 0评估为false时,它不会进一步迭代。

如果您将代码扩展为以下内容,则可以自行检查:

|> Stream.take_while(fn (x) -> IO.inspect(x); x > 0 end)

也许你想要使用Stream.filter/2

希望能帮助您解决问题!