lud
How to halt stream while returning a last value
Hello,
I have this example where I would like a stream transformation to return the whole input list up to the third atom, included.
input = ["a", "b", "c", "d", :x, :y, "e", "f", :z, "g", "h", "i", :aa, :bb, "j"]
Expected output:
["a", "b", "c", "d", :x, :y, "e", "f", :z]
All I can do for now is to return:
["a", "b", "c", "d", :x, :y, "e", "f"]
Of course it would be very easy without the constraint: Further elements from the stream should not be processed once the final atom is found in the stream.
Do you know how I should do that?
Thank you!
Some test code:
defmodule Demo do
def run do
input = ["a", "b", "c", "d", :x, :y, "e", "f", :z, "g", "h", "i", :aa, :bb, "j"]
wanted_atoms = 3
input
#
# Classifier function. In real application it costs money to run so we never
# want to call it if we are not going to process its result.
|> Stream.map(fn
"g" -> raise ~s(should not process "g")
value when is_atom(value) -> {:atom, value}
value -> {:other, value}
end)
# Take 3 atoms if we find them in the stream, take the whole stream
# otherwise.
|> Stream.transform(
_start_fun = fn -> 0 end,
_redux_fun = fn
{:atom, value}, atom_count when atom_count == wanted_atoms - 1 -> {:halt, {:last, value}}
{:atom, value}, atom_count -> {[value], atom_count + 1}
{:other, value}, atom_count -> {[value], atom_count}
end,
__last_fun = fn
# Not called when the reducer returns :halt
{:last, value} -> {[value], nil}
n when is_integer(n) -> {:halt, nil}
end,
_after_fun = fn acc -> :ok end
)
|> Enum.to_list()
|> IO.inspect(limit: :infinity, label: "final")
end
defp get_score(2), do: {:ok, 1234}
defp get_score(_), do: {:error, :nope}
end
Demo.run()
Marked As Solved
al2o3cr
You can do it with a sentinel value, since each step of Stream.transform can emit multiple results:
|> Stream.transform(
fn -> 0 end,
fn
{:atom, a}, atom_count when atom_count+1 < wanted_atoms ->
{[a], atom_count+1}
{:atom, a}, _atom_count ->
{[a, :__no_more_atoms], :ok}
{_, v}, atom_count ->
{[v], atom_count}
end,
fn _ -> :ok end
)
|> Stream.take_while(& &1 != :__no_more_atoms)
The transform produces a stream with an extra value on the end when the last wanted atom is seen, then take_while snips it off and terminates the stream.
5
Also Liked
benwilson512
Author of Craft GraphQL APIs in Elixir with Absinthe
I have also used Stream.concat for this eg. Stream.concat(other_stream, [:ending_value])
2
Popular in Questions
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this:
...
New
As a follow up to my earlier question:
I have the code compiling and running but not getting a successful login from the rest server. ...
New
I want to know absolute current module path. In python i could do that: os.path.abspath(__file__) Does elixir have anything similar?
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
Other popular topics
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set?
Thanks.
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode.
The solution seems to be, in a hyphena...
New
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I'm writing a test for one of t...
New
Hello,
I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these
buyer = %{
id: ...
New
I tried installing
elixir 1.11.2
erlang 23.3.4
via asdf in my zsh shell. Enabled the versions locally and globally.
When I list them ...
New
Hello, I have map which I want to convert it to string like this:
the map:
%{last_name: "tavakkoli", name: "shahryar"}
the string I ne...
New
Hi all,
I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I'm trying to use Postg...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New







