elixir not updating values in mapset using enum.each

随声附和 提交于 2019-12-24 07:32:39

问题


map_set = MapSet.new()
Enum.each(filtered_list, fn x -> map_set = MapSet.put(MapSet.new(map_set),x)

Here filtered_list is a list containing string but when I am printing map_set it is returning an empty set. Why?


回答1:


Your code is equivalent to this this:

map_set = MapSet.new()

Enum.each(filtered_list, fn x ->
  other = MapSet.put(MapSet.new(map_set), x)
end)

The map_set you assign to inside the enum is a local variable, it's not related to the map_set outside the enum. It may as well be called other, because you are discarding the variable. Elixir is an immutable language, so you need to assign the result of the enumerable to map_set.

If you just want to convert a list to a set, you can simply do:

MapSet.new(filtered_list)



回答2:


For each item in filtered_list you're creating a new MapSet in the scope of the callback function. You can't rebind map_set of the upper scope in the callback function (although you can read it, rebinding it just makes a new scoped variable). Instead you should use the returned value of expressions. For example

filtered_list = ["foo", "bar"]
map_set = MapSet.new()         # this is actually redundant 

map_set = Enum.reduce(filtered_list, map_set, fn filter, map_set ->
  MapSet.put(map_set, filter)
end)

This is true of if, case, cond, ... you use the returned value of your expression.

something = "foo"

if true do
  something = something <> "bar"
end

# it's still foo
something

if you want to rebind something you have to use the returned value of the if expression

something = "foo"

something =
  if true do
    something <> " bar"
  end

# is "foo bar"
something

By the way, you can just pass the filtered_list to MapSet.new/1 and if you need any transformation you can use MapSet.new/2



来源:https://stackoverflow.com/questions/55177308/elixir-not-updating-values-in-mapset-using-enum-each

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!