0

I am new to Elixir language and I am having some issues while writing a piece of code.

What I am given is a 2D array like

list1 = [
           [1 ,2,3,4,"nil"],
           [6,7,8,9,10,],
           [11,"nil",13,"nil",15],
           [16,17,"nil",19,20] ]

Now, what I've to do is to get all the elements that have values between 10 and 20, so what I'm doing is:


final_list = []
Enum.each(list1, fn row ->   
Enum.each(row, &(if (&1 >= 10 and &1 <= 99) do final_list = final_list ++ &1 end)) 
end
)

Doing this, I'm expecting that I'll get my list of numbers in final_list but I'm getting blank final list with a warning like:

warning: variable "final_list" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
  iex:5

:ok

and upon printing final_list, it is not updated.

When I try to check whether my code is working properly or not, using IO.puts as:

iex(5)> Enum.each(list1, fn row ->                                              ...(5)> Enum.each(row, &(if (&1 >= 10 and &1 <= 99) do IO.puts(final_list ++ &1) end))     
...(5)> end
...(5)> )

The Output is:

10


11
13
15
16
17
19
20
:ok

What could I possibly be doing wrong here? Shouldn't it add the elements to the final_list? If this is wrong ( probably it is), what should be the possible solution to this?

Any kind of help will be appreciated.

2 Answers2

0

As mentioned in Adam's comments, this is a FAQ and the important thing is the message "warning: variable "final_list" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)" This message actually indicates a very serious problem.

It tells you that the assignment "final_list = final_list ++ &1" is useless since it just creates a local variable, hiding the external one. Elixir variables are not mutable so you need to reorganize seriously your code.

bortzmeyer
  • 34,164
  • 12
  • 67
  • 91
  • This is kinda misleading, because [tag:elixir] variables are rebindable, and `final_list = final_list ++ &1` would have made a total sense if it was not done inside another scope. That said, the issue here is scoping, not mutability. – Aleksei Matiushkin Oct 08 '22 at 10:59
0

The simplest way is

final_list = 
  for sublist <- list1,
      n <- sublist,
      is_number(n),
      n in 10..20,
      do: n

Note that every time you write final_list = ..., you actually declare a new variable with the same name, so the final_list you declared inside your anonymous function is not the final_list outside the anonymous function.

Aetherus
  • 8,720
  • 1
  • 22
  • 36