How to end for comprehension early

I’m trying to figure out how to use Elixir’s version of for comprehensions.

The Phoenix live view generator creates this code in the live/page_live.ex file to get the search results:

    for {app, desc, vsn} <- Application.started_applications(),
        app = to_string(app),
        String.starts_with?(app, query) and not List.starts_with?(desc, ~c"ERTS"),
        into: %{},
        do: {app, vsn}

How could I go about making this return at most 5 results? I tried using Enum.with_index on the first line and adding an index < 5 filter, but that just limited the search space to the first 5 dependencies.

You can not limit “length” or “size” of the result of a comprehension.

You can pass the result to Enum.take/2 or Enum.sort/2,3 and then Enum.take/2.

I’d remove the into: %{} though then, and pipe the sorted and shortened list into Map.new/1.

for comprehension is greedy, so it would pass through the whole list no matter what.

Some time ago I have implemented lazy comprehension with LazyFor having nearly the same syntax as for (but it’s somewhat limited yet.)

iex|1 ▶ import LazyFor
iex|2 ▶ stream {app, desc, vsn} <- Application.started_applications(),
...|2 ▶   app = to_string(app),
...|2 ▶   String.starts_with?(app, "") and not List.starts_with?(desc, ~c"ERTS"),
...|2 ▶   take: 5,   # THIS
...|2 ▶   do: {app, vsn}
[
  {"lazy_for", '0.3.0'},
  {"benchfella", '0.3.5'},
  {"hex", '0.20.5'},
  {"inets", '7.1.2'},
  {"ssl", '9.6'}
]```