我有一张这样的地图:
%{"browser_name" => "Chrome", "platform" => "linux"}
,我需要将其转换为关键字列表:
[browser_name: "Chrome", platform: "linux"]
实现此目标的最佳方法是什么?
答案 0 :(得分:3)
为了将来的读者,我会把它放在这里。
虽然肯定会在这里和那里盲目致电String.to_atom/1
,但由于该方法容易受到原子DoS攻击,因此强烈建议。
以下是Erlang文档的摘录:
原子不会被垃圾收集。一旦创建了原子,就永远不会删除它。如果达到原子数限制(默认为1,048,576),则模拟器终止。
因此,在连续运行的系统中,将任意输入字符串转换为原子可能很危险。如果仅允许某些定义明确的原子作为输入,则可以使用
list_to_existing_atom/1
来防止拒绝服务攻击。 (例如,可以通过在模块中简单地使用所有原子并加载该模块来创建所有允许的原子。)— http://erlang.org/doc/efficiency_guide/commoncaveats.html#list_to_atom-1
也就是说,无论您是否从外部不受信任的来源收到地图(例如,是调用API的参数之类的东西),您都绝对不能使用String.to_atom/1
,并且应该使用String.to_existing_atom/1
。
否则,入侵者只有一个简单的密钥随机生成器,这会炸毁您的 ErlangVM 。
答案 1 :(得分:1)
这行不通吗
def ConvertMapToKList(dict) do
Enum.map(dict, fn({key, value}) -> {String.to_existing_atom(key), value} end)
end
答案 2 :(得分:0)
您可以使用C
函数并将转换函数作为第二个参数传递。
Keyword.new
尽管这基本上等同于@NiteRain接受的答案,但我认为它更加明确,可以向将来的代码读者展示您的意图。