删除 Elixir 映射中的外部列表键以提取内部映射

Remove outer list key in Elixir map to extract inner map

{我正在尝试删除如下所示的地图外键:

    %{
  orders: [
    %{"000147815" => "2018-08-29T11:37:16Z"},
    %{"000147814" => "2018-08-07T06:35:22Z"},
    %{"000147813" => "2018-08-03T13:07:07Z"},
    %{"000147812" => "2018-07-31T11:41:54Z"},
    %{"000147811" => "2018-07-31T11:35:00Z"},
    %{"000147810" => "2018-07-24T14:52:40Z"}
     ]
     }

获得:

%{"000147815" => "2018-08-29T11:37:16Z",
"000147814" => "2018-08-07T06:35:22Z",
"000147813" => "2018-08-03T13:07:07Z",
"000147812" => "2018-07-31T11:41:54Z",
"000147811" => "2018-07-31T11:35:00Z",
"000147810" => "2018-07-24T14:52:40Z"}

我试过模式匹配和提取值并将它们压缩到列表中,但无济于事。这似乎是一个非常简单的步骤,但我被卡住了。有没有切图的方法?

编辑

感谢您的努力,通过将我的数据直接枚举到地图中,我的问题得到了解决。

 def retrieve_order_data(json) do
    json
    |> Enum.map(fn order ->
          {order["cat"]["order_number"], order["cat"]["order_date"]}
    end)
    |> Enum.into(%{})
  end

Comprehensions 非常适合使用可枚举对象。它们不是每个人的最爱,也不是唯一的解决方案,但我非常喜欢它们。

iex> outer = %{
...>   orders: [
...>     %{"000147815" => "2018-08-29T11:37:16Z"},
...>     %{"000147814" => "2018-08-07T06:35:22Z"},
...>     %{"000147813" => "2018-08-03T13:07:07Z"},
...>     %{"000147812" => "2018-07-31T11:41:54Z"},
...>     %{"000147811" => "2018-07-31T11:35:00Z"},
...>     %{"000147810" => "2018-07-24T14:52:40Z"}
...>   ]
...> }
iex> for order <- outer.orders, {id, time} <- order, into: %{}, do: {id, time}
%{
  "000147810" => "2018-07-24T14:52:40Z",
  "000147811" => "2018-07-31T11:35:00Z",
  "000147812" => "2018-07-31T11:41:54Z",
  "000147813" => "2018-08-03T13:07:07Z",
  "000147814" => "2018-08-07T06:35:22Z",
  "000147815" => "2018-08-29T11:37:16Z"
}

但您可以很容易地对其进行模式匹配:

iex> %{orders: inner} = %{
...>   orders: [
...>     %{"000147815" => "2018-08-29T11:37:16Z"},
...>     %{"000147814" => "2018-08-07T06:35:22Z"},
...>     %{"000147813" => "2018-08-03T13:07:07Z"},
...>     %{"000147812" => "2018-07-31T11:41:54Z"},
...>     %{"000147811" => "2018-07-31T11:35:00Z"},
...>     %{"000147810" => "2018-07-24T14:52:40Z"}
...>   ]
...> }
iex> inner
[
  %{"000147815" => "2018-08-29T11:37:16Z"},
  %{"000147814" => "2018-08-07T06:35:22Z"},
  %{"000147813" => "2018-08-03T13:07:07Z"},
  %{"000147812" => "2018-07-31T11:41:54Z"},
  %{"000147811" => "2018-07-31T11:35:00Z"},
  %{"000147810" => "2018-07-24T14:52:40Z"}
]

您可以通过多种方式实现这一目标。例如,您可以使用 Enum.reduce/3 轻松解决它。喜欢:

iex> m = %{
...>   orders: [
...>     %{"000147815" => "2018-08-29T11:37:16Z"},
...>     %{"000147814" => "2018-08-07T06:35:22Z"},
...>     %{"000147813" => "2018-08-03T13:07:07Z"},
...>     %{"000147812" => "2018-07-31T11:41:54Z"},
...>     %{"000147811" => "2018-07-31T11:35:00Z"},
...>     %{"000147810" => "2018-07-24T14:52:40Z"}
...>   ]
...> }
%{
  orders: [
    %{"000147815" => "2018-08-29T11:37:16Z"},
    %{"000147814" => "2018-08-07T06:35:22Z"},
    %{"000147813" => "2018-08-03T13:07:07Z"},
    %{"000147812" => "2018-07-31T11:41:54Z"},
    %{"000147811" => "2018-07-31T11:35:00Z"},
    %{"000147810" => "2018-07-24T14:52:40Z"}
  ]
}
iex> Enum.reduce(m.orders, %{}, fn x, acc -> Map.merge(acc, x) end)
%{
  "000147810" => "2018-07-24T14:52:40Z",
  "000147811" => "2018-07-31T11:35:00Z",
  "000147812" => "2018-07-31T11:41:54Z",
  "000147813" => "2018-08-03T13:07:07Z",
  "000147814" => "2018-08-07T06:35:22Z",
  "000147815" => "2018-08-29T11:37:16Z"
}

如果订单中的地图有多个 {key, value},它们也会被添加到生成的地图中。但是请注意,如果其中一个键出现在多个映射中,则只会保留最后一个值。但这似乎并不影响您的用例