【问题标题】:How to iterate through maps in list, and store their values to variable如何遍历列表中的地图,并将它们的值存储到变量中
【发布时间】:2021-01-22 10:15:01
【问题描述】:

我对 erlang 很陌生,我正在尝试做这样的事情:

有一个地图列表,例如:

  List = [#{id => 1, start=> 'Y', memberName => "MemberName" },
          #{id => 2, start=> 'N', memberName => "MemberName" }],

已编辑

然后我想遍历列表中的每个映射并将memberNameid 的每个值存储到一个单独的变量中。

如何实现这样的目标?

【问题讨论】:

    标签: list erlang maps


    【解决方案1】:

    在这种情况下,您还可以使用列表理解和模式处理:

    1> List = [#{id => 1, start=> 'Y', memberName => "MemberName1" },#{id => 2, start=> 'N', memberName => "MemberName2" }],
    2> [X || #{memberName := X} <- List].
    ["MemberName1","MemberName2"]
    3>
    

    请注意,与@2240 解决方案相比的主要行为差异是,如果列表包含不同的元素,它不会失败。在这种情况下,我不知道您的期望是什么。

    3> L2 = List ++ [atom,#{nomembername => no}].                       
    [#{id => 1,memberName => "MemberName1",start => 'Y'},
     #{id => 2,memberName => "MemberName2",start => 'N'},
     atom,
     #{nomembername => no}]
    4> [X || #{memberName := X} <- L2].                                 
    ["MemberName1","MemberName2"]
    5> lists:foldl(fun(Elem, AccIn) -> lists:append([maps:get(memberName, Elem)], AccIn) end,  [], List).
    ["MemberName2","MemberName1"]
    6> lists:foldl(fun(Elem, AccIn) -> lists:append([maps:get(memberName, Elem)], AccIn) end,  [], L2).  
    ** exception error: {badmap,atom}
         in function  maps:get/2
            called as maps:get(memberName,atom)
         in call from erl_eval:do_apply/6 (erl_eval.erl, line 684)
         in call from erl_eval:expr/5 (erl_eval.erl, line 232)
         in call from erl_eval:expr_list/6 (erl_eval.erl, line 888)
         in call from erl_eval:expr/5 (erl_eval.erl, line 411)
         in call from lists:foldl/3 (lists.erl, line 1263)
    7>
    

    [编辑]

    我不确定你想做什么。在 erlang 中,列表是一种非常基本的结构,用于处理“多个”结果。然后,您可以使用众多列表迭代器之一来处理其元素:foreach、map、foldl、foldr、mapfoldl、mapfoldr 或构建您自己的递归函数。

    为了朝着您的方向走得更远,有两种情况,具体取决于您的初始列表具有在您编写和编译应用程序时已知的固定长度。

    如果是,而且似乎不太可能,您可以简单地将结果列表与变量列表匹配,如下代码所示:

    8> [Name1,Name2] = [X || #{memberName := X} <- List].                                                
    ["MemberName1","MemberName2"]
    9> Name1.
    "MemberName1"
    10> Name2.
    "MemberName2"
    11> 
    

    如果列表的长度可能不同或未知,则无法将每个名称分配给单个变量。您必须将结果分配给名称列表,然后使用此列表,或者遍历地图的初始列表并一次处理一个名称。这是一个使用列表的示例:foreach/2:

    Names = [X || #{memberName := X} <- List],
    lists:foreach(fun(X) -> do_something(X) end,Names),
    ...
    or
    lists:foreach(fun(#{memberName := X}) -> do_something(X) end,List),
    ...
    

    【讨论】:

    • 这看起来不错,但我仍然想将这些值存储在单独的变量中,每个变量都包含一个字符串,不希望它们在列表中......希望我不会在这里遗漏一些明显的东西
    • 问题是,在遍历列表中的每个映射时,我需要在每次迭代(映射)中获取超过 1 个键/值,假设我需要每个映射的 id 和 memberName 并执行在那个迭代里面有一些东西。也许我应该事先将该地图转换为元组或列表?所以我有价值观清单,只选择我感兴趣的价值观。希望我足够清楚,避免混淆
    • 然后你可以一次在多个键上使用模式匹配,像这样:lists:foreach(fun(#{memberName := Name, id :=ID}) -&gt; do_something(Name,ID) end,List)
    【解决方案2】:

    您可以使用fold 来执行此操作。

    > List = [#{id => 1, start=> 'Y', memberName => "MemberName" },
              #{id => 2, start=> 'N', memberName => "MemberName" }],
    > lists:foldl(fun(Elem, AccIn) -> lists:append([maps:get(memberName, Elem)], AccIn) end,  [], List).
    ["MemberName","MemberName"]
    

    【讨论】:

    • 我编辑了原始问题,我希望将这些值(字符串)存储在单独的变量中,而不是全部存储在一个列表中:)
    猜你喜欢
    • 2020-07-07
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多