kalindkaria

kalindkaria

Map.update inside for loop

Hi, I’ve just started learning Elixir.
For one of the applications I’m developing, I have the following code:

use Bitwise
sensor_data = %{sensor1: 0}
for n <- 0..9, do: sensor_data = Map.update!(sensor_data, :sensor1, &(&1 ||| (1 <<< n)))

This produces following output:

[
  %{sensor1: 1},
  %{sensor1: 2},
  %{sensor1: 4},
  %{sensor1: 8},
  %{sensor1: 16},
  %{sensor1: 32},
  %{sensor1: 64},
  %{sensor1: 128},
  %{sensor1: 256},
  %{sensor1: 512}
]

But the expected output should be:

[
  %{sensor1: 1},
  %{sensor1: 3},
  %{sensor1: 7},
  %{sensor1: 15},
  %{sensor1: 31},
  %{sensor1: 63},
  %{sensor1: 127},
  %{sensor1: 255},
  %{sensor1: 511},
  %{sensor1: 1023}
]

If I run the following statement in iex session the sensor_data map gets updated like this:

sensor_data = Map.update!(sensor_data, :sensor1, &(&1 ||| (1 <<< 0)))
%{sensor1: 1}
sensor_data = Map.update!(sensor_data, :sensor1, &(&1 ||| (1 <<< 1)))
%{sensor1: 3}
sensor_data = Map.update!(sensor_data, :sensor1, &(&1 ||| (1 <<< 2)))
%{sensor1: 5}

Can you help me understand why does the Map.update!/3 doesn’t work inside a for loop?
I also tried with Map.update/4 Map.replace!/3 but no luck.

Most Liked

stefanchrobot

stefanchrobot

The “assignment” inside the for loop has no effect, it creates a new variable on each loop iteration. I think you might be looking for Enum.reduce:

Enum.reduce(0..9, %{sensor1: 0}, fn n, sensor_data ->
  Map.update!(sensor_data, :sensor1, &(&1 ||| (1 <<< n)))
end)
LostKobrakai

LostKobrakai

If you really want to use for you can. Since a few versions back it also supports reductions.

use Bitwise
sensor_data = %{sensor1: 0}
new_sensor_data = 
  for n <- 0..9, reduce: sensor_data do
    acc -> Map.update!(acc, :sensor1, &(&1 ||| (1 <<< n)))
  end
stefanchrobot

stefanchrobot

See also: https://elixir-lang.org/getting-started/case-cond-and-if.html#if-and-unless

This is also a good opportunity to talk about variable scoping in Elixir. If any variable is declared or changed inside if, case, and similar constructs, the declaration and change will only be visible inside the construct. For example:

iex> x = 1
1
iex> if true do
...>   x = x + 1
...> end
2
iex> x
1

In said cases, if you want to change a value, you must return the value from the if:

iex> x = 1
1
iex> x = if true do
...>   x + 1
...> else
...>   x
...> end
2

Last Post!

kalindkaria

kalindkaria

Thanks @LostKobrakai and @kokolegorille !
I missed out this :reduce option in Comprehensions. I am able to recall now.
Documentation about :reduce for anyone to refer in future:

Where Next?

Popular in Chat/Questions Top

ericmachine88
Hi all, I am currently on this course https://www.ludu.co/course/discover-elixir-phoenix Half a way thru, and struggled a bit.. someti...
New
asfand
I already created an Elixir Phoenix app for learning purpose. In this app students of our collage will create profiles, and will chat wit...
New
pietrofxq
I’ve bought the following books: Programming Elixir 1.6 Programming Phoenix 1.4 Programming Ecto Functional Web Development with Elixir...
New
phykos
In Ruby, which is very similar to Elixir I do this: def test yield end test do puts("sup there") end Here, the yield keyword will be...
New
satoru
I’m working on the “Bob” exercise on the Elixir Track in Exercism. I am testing for uppercase letter with this simple check: c in ?A..?Z...
New
Santheepkumar
Hi all, I am a Fullstack JS developer for last 2 years. I need a good guide to learn elixer. Any suggestions please
New
ariandanim
Hello all, I am still learning Elixir, then go into Phoenix, i am try search in google but find the programming phoenix 1.4, another for...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44532 311
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement