如何在Elixir中将非原子键的嵌套属性列表转换为映射?
在Elixir中将嵌套列表转换为嵌套映射的方法
问题描述
我有如下Elixir列表:
nl = [ {"_id", "idhere"}, {"App-Version", "version_here"}, {"TX-ID", "tx-id-here"}, {"Method", "method-here"}, {"Body", {[ {"Identification", [ {"A", "A-Val"}, {"B", "B-Val"}, {"C", "C-Val"}, {"D", "D-Val"} ]}, {"CurrentTime", "2023-02-23T16:40:13+05:30"}, {"Names", ["Name1", "Name2"]} ]}} ]
如何将其转换为嵌套映射?我尝试使用Map.new/1,但作为Elixir新手没能成功实现。
解决方案
Map.new/1只能处理顶层的键值对列表,但你的数据里存在嵌套的元组包裹列表、多层键值对列表的情况,需要递归处理所有层级的结构。可以写一个递归转换函数:
defmodule ListToMap do def convert(list) when is_list(list) do Enum.into(list, %{}, fn {key, value} -> {key, convert_value(value)} end) end defp convert_value({list}) when is_list(list) do convert(list) end defp convert_value(list) when is_list(list) do if Enum.all?(list, &match?({_, _}, &1)) do convert(list) else list end end defp convert_value(value), do: value end
使用方法
调用这个函数就能得到嵌套映射:
map = ListToMap.convert(nl)
转换结果
最终得到的嵌套映射结构如下:
%{ "_id" => "idhere", "App-Version" => "version_here", "TX-ID" => "tx-id-here", "Method" => "method-here", "Body" => %{ "Identification" => %{ "A" => "A-Val", "B" => "B-Val", "C" => "C-Val", "D" => "D-Val" }, "CurrentTime" => "2023-02-23T16:40:13+05:30", "Names" => ["Name1", "Name2"] } }
函数逻辑说明
convert/1:处理顶层的键值对列表,将其转为映射,同时对每个值调用convert_value/1递归处理嵌套结构。convert_value({list}):专门处理{[...]]}这类元组包裹列表的特殊结构,提取内部列表后继续转换。convert_value(list):判断列表是否全是{键, 值}形式的元组,是则转为映射,否则保留原列表(比如Names对应的数组)。- 默认分支
convert_value/1:直接返回字符串、数字这类非嵌套结构的原始值。
内容的提问来源于stack exchange,提问作者KoolQuark
相关产品推荐
相关产品推荐

