Kotaa
Kotaa

Reputation: 201

Passing arguments to a function and calling it via "&"

Is there any way to shorten these kinds of method calls:

aaa = Enum.find(Statuses, fn(x) -> x.name == :pending end) 

to something like this:

aaa = Enum.find(Statuses, &==, [:name, :pending])

That is, to pass the arithmetic operator "==", structure field name name and value :pending as arguments.

Upvotes: 0

Views: 111

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Also, the answer by Dogbert is perfect, as usual, I would put mine here too, for the sake of formatting.

This is a perfect example of when Elixir “prevents” you from doing things in a wrong way. If there is no such method on hand, it pretty much means the approach is wrong.

You are looking for a struct, that has a name having value :pending. Do that explicitly, with Kernel.match?/2 macro:

iex> [%{n: 1, name: :pending}, %{n: 2, name: :complete}]
     |> Enum.find(&match?(%{name: :pending}, &1))
%{n: 1, name: :pending}

Quote from the documentation:

match?/2 is very useful when filtering of finding a value in an enumerable:

list = [{:a, 1}, {:b, 2}, {:a, 3}]
Enum.filter list, &match?({:a, _}, &1)
#⇒ [{:a, 1}, {:a, 3}]

Upvotes: 0

Dogbert
Dogbert

Reputation: 222128

You can use the partial application syntax for this:

aaa = Enum.find(Statuses, &(&1.name == :pending))

or

aaa = Enum.find(Statuses, & &1.name == :pending)
iex(1)> f = &(&1.name == :pending)
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(2)> f.(%{name: :pending})
true
iex(3)> f.(%{name: :complete})
false

Upvotes: 4

Related Questions