Hello, I am trying to add another element to a list and for some reason it is giving me errors. I am new to elixir and I have just started, please help me figure this out.
Code:
def forloop(list, y) do
if y > 0 do
list = Enum.map list, fn(x) ->
x - 1
if (x == 0) do
x + 6
list = list ++ [9]
end
end
forloop(list, y - 1)
end
end
How will that help? After 1 loops if the starting list was [1, 2, 4], I want the new value to be [6, 1, 3, 8] and after another loop it would be [5, 6, 2, 7, 8].
Enum.reduce takes a function like Enum.map but the function has two arguments, the current item, and the accumulator. So you could use the list as the accumulator.
Values in elixir are not mutable. You’re doing a lot of things and then just throwing the answer away.
list = Enum.reduce list, list, fn(x, acc) ->
x - 1 # result gets thrown away
if (x == 0) do
x + 6 # result gets thrown away
acc ++ [9]
end # result is nil if (x != 0)
end
Ok, so from what I understood I made the code this:
list = Enum.map list, fn(x) ->
x = x - 1
if (x == 0) do
x + 6
else
x
end
end
This doesn’t help me with adding a new element to the list but it works for x. Can you help me make it add a new element? I tried this and it didn’t work:
list = Enum.reduce list, list, fn(x, acc) ->
x = x - 1
if (x == 0) do
x + 6
acc ++ [9]
else
x
end
end
When you reduce, you are building the list back up from scratch. This allows you to both update the existing items, and add new items. The result of your anonymous function should always be the new, updated acc. Try:
list =
Enum.reduce(list, [], fn item, acc ->
case item - 1 do
0 ->
[6, 9 | acc]
x ->
[x | acc]
end
end)
defmodule IAmCool do
def forloop(list0, y) do
if y > 0 do
list1 =
Enum.map(list0, fn x0 ->
x0 - 1
if x0 == 0 do
x0 + 6
list2 = list0 ++ [9]
end
end)
forloop(list1, y - 1)
end
end
end
warning: variable “list2” is unused (if the variable is not meant to be used, prefix it with an underscore) #cell:10: IAmCool.forloop/2
Also x + 6 does does nothing if you don’t assign it to a variable. also due to lexical scope the variables assignment do not escape the if block.
Please if you don’t mind, can you translate it to an if statement instead of case statement. It works fine but I want to better understand this solution.
defmodule IAmCool do
# First thing, SnakeCase is used for Modules, undercore is use for function names and variables.
# Secondly, use pattern matching to avoid ives (if)
def for_loop(list0, y) when y > 0 do
list1 =
Enum.map(list0, fn x0 ->
# Assign the result of x+1 to a variable
x1 = x0 - 1
# read inside the if block to know why I do this.
{list3, x3} =
if x1 == 0 do
# Assign the result of x+6 to a variable
x2 = x1 + 6
# here you want to modify the value of an outter variable (list0) so
# doing: list0 = list0 ++ [9]
# will not work as variables do not leak out if blocks in Elixir.
# so we just return and assign the result to variables via pattern matching
list2 = list0 ++ [9]
{list2, x2}
end
# alight, now we return list0
# and the question is. What do you need x3 for?
list3
end)
for_loop(list1, y - 1)
end
def for_loop(_list0, _y),
do: nil
end