Changing global variable inside a map function

I’m trying to change a global variable inside a map function, I tried the following but it didn’t work well

 xx=0
      imp = Map.get(params, "i")
      |> Enum.map(fn %{"b" => b} = node ->
        Map.put(
          node, 
          "b",
          Float.round((b+ b* a)*(1 + a),5)
        )
        xx=5
      end)

and I tried to pass the “xx” as a parameter to the function and it didn’t work what should I do?

You can not change variables from an outer scope. You need to return the new value from your function and assign it in the caller.

1 Like

I tried the following

xx=0
      imp = Map.get(params, "i")
      {xx,map} = Enum.map(imp,fn %{"b" => b} = node ->
        xx=5
        Map.put(
          node, 
          "b",
          Float.round((b+ b* a)*(1 + a),5)
        )
      end)

and get the following error

no match of right hand side value

Because Enum.map/2 returns a list.

And also, each item in the list will be a map, you do not return the 5 from your called function in any way.

If you could explain more indepth what you want to achieve we could help you, though if you just want to statically set xx to 5, then do xx = 5 instead of xx = 0

1 Like

What I’m really trying to do is the following

In params I have multiple “i” each one also have a specific “id” like the following

{
    "id": "yyyyy",
    "i": [{
        "id": "1",
        "b":"2"}
       ,{
        "id": "2",
        "b":"5"
        }]
}

I want to change each “b” using the equation Float.round((b+ b* a)*(1 + a),5) when “a” is a number

I have to know the original “b” and the final “b” and store them inside an array for each of them

so then, for example, I can get the original and the final of “id=1” like this

new_arr[i][1][original]
new_arr[i][1][final]

so I tried to define this array as global variable to use it later

The global variable is a common approach in imperative languages, but not the one you should use in Elixir. Try, for example, to use reduce instead of map so you have control on the return values.

Also consider that Elixir data structures are immutable, so when you put a value into a map you get a new map, as opposed to mutating the original map. The original is still available as long as you don’t rebind its variable. Would this help you to keep track of the “original” and the “final” b?

1 Like

I still do not see what xx is in this example…

final = Enum.map(imp, fn %{"b" => b} = node ->
  b = String.to_integer(b)
  %{node | "b" => Float.round((b+b*a)*(1+a),5) }
end)

Original data is still in imp, while recalculated data is now in final. This assumes that a is defined somewhere else in scope.

1 Like