эликсир не обновляет значения в mapset используя enum.each - PullRequest
1 голос
/ 15 марта 2019
map_set = MapSet.new()
Enum.each(filtered_list, fn x -> map_set = MapSet.put(MapSet.new(map_set),x)

Здесь Filter_list - это список, содержащий строку, но когда я печатаю map_set, он возвращает пустой набор.Почему?

Ответы [ 2 ]

3 голосов
/ 15 марта 2019

Для каждого элемента в filtered_list вы создаете новый MapSet в области функции обратного вызова.Вы не можете перепривязать map_set верхней области видимости в функции обратного вызова (хотя вы можете прочитать ее, перепривязка просто создает новую переменную области видимости).Вместо этого вы должны использовать возвращаемое значение выражений.Например,

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)

Это верно для if, case, cond, ... вы используете возвращаемое значение вашего выражения.

something = "foo"

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

# it's still foo
something

, если выхотите перепривязать something вы должны использовать возвращаемое значение выражения if

something = "foo"

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

# is "foo bar"
something

Кстати, вы можете просто передать filtered_list в MapSet.new/1и если вам нужно какое-либо преобразование, вы можете использовать MapSet.new/2

2 голосов
/ 15 марта 2019

Ваш код эквивалентен этому:

map_set = MapSet.new()

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

map_set, который вы назначаете внутри перечисления, является локальной переменной, она не связана с map_set вне перечисления. Его также можно назвать other, потому что вы отбрасываете переменную. Эликсир является неизменным языком, поэтому вам нужно присвоить результат перечисляемого для map_set.

Если вы просто хотите преобразовать список в набор, вы можете просто сделать:

MapSet.new(filtered_list)
...