Reputation: 484
I am wondering, what is the best way to obtain results by the given algorithm? The current solution doesn't help because results are nil. How can I make the variable results accessible in iterate_json without passing it as an argument?
def lookup(json) do
results = []
iterate_json(json, fn(x) ->
if x["title"] =~ "sunt" do
results = [x|results]
end
end)
results
end
def iterate_json([head|tail],f) do
f.(head)
iterate_json(tail,f)
end
def iterate_json([],f), do: nil
Upvotes: 0
Views: 327
Reputation: 121000
There are few different issues with this code. The main is one cannot access the parent context from within a closure (even in Ruby that won’t change the results
variable:
results = nil
fn(x) -> results = 42 end.()
results
#⇒ nil
warning: variable "
results
" is unusedNote variables defined inside
case
,cond
,fn
,if
and similar do not leak. If you want to conditionally override an existing variable "results
", you will have to explicitly return the variable. For example:
The above is what iex
spits out when one tries to execute this code.
How can I make the variable
results
accessible initerate_json
without passing it as an argument?
It’s accessible in iterate_json
. The value that was set upfront is captured and used within a closure. What you cannot do, is you cannot change it from inside a closure.
What you are trying to achieve, is actually a Enum.reduce/3
operation:
def lookup(json) do
Enum.reduce(json, [], fn x, acc ->
if x["title"] =~ "sunt", do: [x|acc], else: acc
end)
end
Upvotes: 1