and I want to “do something” to each element in a reduce loop, removing elements that error/fail while “doing something”.
It might look like this:
my_list
|> Enum.reduce([], fn x, acc ->
with {:ok, result: result} <- do_something(x) do
acc ++ [result]
else
_ -> acc
end
end)
That gets me the result I want.
However, I know that in Elixir it is more efficient to do [result] ++ acc than it is to do acc ++ [result].
So, for large lists, would it be more efficient to use [result] ++ acc in the reduce loop and then in my pipeline use Enum.reverse to put the list back in original order?
Alternatively to Enum.flat_map/2 you can use a for-comprehension:
for with 1-element list
for i <- my_list,
# We have to wrap the `do_something` call in a list to use `<-` for filtering
{:ok, result: result} <- [do_something(i)] do
result
end
for with filter clause
for i <- my_list,
ok_or_error = do_something(i),
match?({:ok, _}, ok_or_error) do
{:ok, result: result} = ok_or_error
result
end