模式与地图上其他元素的匹配

时间:2018-08-08 00:29:24

标签: dictionary pattern-matching elixir

我只是想知道是否有一种干净的方法可以从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

3 个答案:

答案 0 :(得分:2)

chartjs函数,该函数接受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

答案 1 :(得分:1)

我会选择旧的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}}

答案 2 :(得分:0)

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