Есть много разных способов, но в описанном сценарии Enum.split_with/2
ваш друг.
[{:ok, 1}, {:error, 2}, {:ok, 3}]
|> Enum.split_with(fn {:error, _} -> true; _ -> false end)
|> case do
{[], oks} ->
oks
{errors, _} ->
errors
|> Enum.map(&elem(&1, 1))
|> IO.inspect(label: "Found errors")
end
Также швейцарский нож Enum.reduce/3
может использоваться как во всех других случаях, когда нужно свернуть список.
[{:ok, 1}, {:error, 2}, {:ok, 3}]
|> Enum.reverse() # needed to prepend below
# preserving the original order
|> Enum.reduce(%{errors: [], oks: []}, fn
{:error, error}, acc ->
%{acc | errors: [error | acc.errors]}
{:ok, ok}, acc ->
%{acc | oks: [ok | acc.oks]}
end)
#⇒ %{errors: [2], oks: [1, 3]}
Как правильно сказал @Daniel в комментариях, «Используются исключения в эликсире как механизм отправки ошибки родительскому процессу и должен использоваться только при наличии ошибки разрыва приложения. ”