How To Return a Element Inside Of Tuple In Anonymous Function

I want to a list without :ok elements.

dates = Enum.map(b, (fn x ->{:ok, date} = Date.from_iso8601(x)  end))              
[
  ok: ~D[2018-02-26],
  ok: ~D[2018-02-27],
  ok: ~D[2018-02-28],
  ok: ~D[2018-03-01],
  ok: ~D[2018-03-02],
  ok: ~D[2018-03-03],
  ok: ~D[2018-03-04]
]

 dates = Enum.map(b, (fn x ->{:ok, date} = Date.from_iso8601(x), return date  end))
** (SyntaxError) iex:10: syntax error before: ','
 dates = Enum.map(b, (fn x ->{:ok, date} = Date.from_iso8601(x) date  end))    
** (SyntaxError) iex:11: syntax error before: date
1 Like

You’re not matching, could be

fn {:ok, date} -> # blah

Then you have access to the date straight off the bat.

If you actually want the list without :ok elements, you can ignore the date

Enum.filter(dates, fn {x, _} -> x != :ok end)

EDIT: what @kokolegorille said, mapping it the way you’re doing is a bit nasty though

More like …

fn x -> {:ok, date} = Date.from_iso8601(x); date  end

{:ok, date} is the result of Date.from_iso8601(x)

3 Likes

@DanCouper instead of filter i want to return only date without :ok

@kokolegorille yes it is working.

Gotcha. Use Date.from_iso8601!. Note the exclamation mark, the functions without them will return the {:ok, date) tuple, with the exclamation mark will not, and will just throw if there’s an error: https://hexdocs.pm/elixir/Date.html#from_iso8601!/2

2 Likes

In elixir i never used ; before. I havent known that a new line auto adds ;.

It’s not particularly idiomatic though, [imo] tends to makes things difficult to read & invites errors as it’s unexpected, split across lines instead if you’re going to do that

(fn x ->
  {:ok, date} = Date.from_iso8601(x)
  date
end)
4 Likes

The coolest form would be

&Date.from_iso8601!(&1)
#or
&Date.from_iso8601!/1
3 Likes

thanks no :ok in Date.from_iso8601!. That is better

I do not like the bang-functions. It is very easy to not see the bang when skimming code (or see it where it actually isn’t).

Therefore I prefer to actually split those into fn x -> {:ok, r} = f.(x); r end or put them into a “service module” as do_something_or_raise.

2 Likes

In that case, wouldn’t that raise a NoMatchClause error if f.(x) fails?

Its a MatchError I think, but often I do not care for what is raised, as long as the process dies.

If I want to properly handle the error, I’d try to avoid the raise at all costs and simply match in a case on the result of f.(x).

1 Like

Ok, thanks for the explanation… and good practice.