问题
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