【问题标题】:Pattern match against the other element of a map与地图的其他元素的模式匹配
【发布时间】:2018-08-10 01:25:25
【问题描述】:

我只是想知道是否有一种干净的方法可以从 Elixir 的地图中获取“其他”元素。 “其他”是指第二个键值对,我不知道它的键。

示例:%{success: boolean, other => value}

这是我能想到的最好的:

case map do
  %{success: true} -> 
     other = map |> Map.delete(:success) |> Map.values |> List.first 
     # Do something with other
  %{success: false} -> 
     error = map |> Map.delete(:success) |> Map.values |> List.first 
     # Do something with error
end

【问题讨论】:

  • 要知道“其他”键的名称,可以使用Map.keys函数并过滤Map.keys(map) |> Enum.reject(&(&1 == :success))

标签: dictionary pattern-matching elixir


【解决方案1】:

Map.pop/3 函数,它接受map 和一个键,并返回一个带有值的元组和一个没有键的映射:

Map.pop %{ a: 1, b: 2 }, :a
# => {1, %{b: 2}}

并将您的代码重构为:

case Map.pop(map, :success) do
  {true, other_map} -> 
     other = other_map |> Map.values |> List.first 
     # Do something with other
  {false, other_map} -> 
     error = other_map |> Map.values |> List.first 
     # Do something with error
end

【讨论】:

    【解决方案2】:

    我会选择老好Enum.reduce/3

    Enum.reduce %{success: true, foo: 42}, %{state: nil, map: %{}}, fn
      {:success, value}, acc -> %{acc | state: value}
      {key, value}, acc -> %{acc | map: Map.put(acc.map, key, value)}
    end
    #⇒ %{map: %{foo: 42}, state: true}
    

    现在您可以在不重复代码的情况下做任何需要的事情。实际上,元组可以很好地收集结果:

    {success, map} =
      Enum.reduce %{success: true, foo: 42}, {nil, %{}}, fn
        {:success, value}, {_, acc} -> {value, acc}
        {key, value}, {state, acc} -> {state, Map.put(acc, key, value)}
      end
    #⇒ {true, %{foo: 42}}
    

    【讨论】:

    • 你是不是重新定义了Map.pop/3
    • @risingprogrammer 一点也不;对于这个特定的应用程序,它可能看起来很相似,但Enum.reduce/3 更加灵活。
    【解决方案3】:
    iex(9)>  map = %{:success => true, {1,2,3} => 10}
    %{:success => true, {1, 2, 3} => 10}
    
    iex(10)> List.first(for {key, val} <- map, key != :success, do: val) 
    10
    

    【讨论】:

    • 这个 imo 比较难读,和模式匹配无关
    • @risingprogrammer:首先,{key, val} 是该代码中的模式匹配。其次,您说:我只想知道是否有一种干净的方法可以从地图中获取“其他”元素
    • 我想对另一个元素进行模式匹配。--任何在 Elixir 中研究过地图超过 10 分钟的人知道你可以't pattern match a key with a variable,所以任何解决方案都不会是模式匹配映射。
    • 我不确定为什么这被否决了。为了熵恒定而投票赞成。
    猜你喜欢
    • 2017-01-24
    • 2015-03-22
    • 2021-06-13
    • 2017-09-29
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多