【问题标题】:elixir not updating values in mapset using enum.eachelixir 不使用 enum.each 更新 mapset 中的值
【发布时间】:2019-03-19 23:18:57
【问题描述】:
map_set = MapSet.new()
Enum.each(filtered_list, fn x -> map_set = MapSet.put(MapSet.new(map_set),x)

这里的filtered_list 是一个包含字符串的列表,但是当我打印map_set 时它返回一个空集。为什么?

【问题讨论】:

    标签: elixir


    【解决方案1】:

    对于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)
    

    ifcasecond 也是如此……您使用表达式的返回值。

    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

    【讨论】:

    • Enum.reduce(filtered_list, map_set, &amp;MapSet.put(&amp;2, &amp;1)) :)
    • @AlekseiMatiushkin 有点神秘,但很糟糕 :)
    • 怎么这么神秘?!根据 José 的说法,捕获是 elixir 的最佳功能 :)
    • @AlekseiMatiushkin 如果何塞这么说,那就是:)
    【解决方案2】:

    你的代码相当于这个:

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

    您在枚举内部分配的map_set 是一个局部变量,它与枚举外部的map_set 无关。它也可以称为other,因为您正在丢弃该变量。 Elixir 是一种不可变语言,所以需要将枚举的结果赋值给map_set

    如果你只是想将一个列表转换为一个集合,你可以这样做:

    MapSet.new(filtered_list)
    

    【讨论】:

    • 谢谢,亚当。我没有检查这个 MapSet.new() 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 2016-11-18
    相关资源
    最近更新 更多