Reputation: 61
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?
Upvotes: 1
Views: 766
Reputation: 23091
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)
Upvotes: 2
Reputation: 1629
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
Upvotes: 4