Elixir:从 query_param 访问元组列表并对其进行迭代

Elixir: accessing a list of tuples from query_param and iterating over it

我正在通过这样的查询参数获取输入:127.0.0.1:8000/pair?A=[{A1,B1},{A2,B2},…,{An,Bn}]。我需要访问该元组列表并更改它,以便结果是两个元组的列表,第一个包含原始列表中每个元组的第一个元素,第二个元组包含每个元组的第二个元素, (像这样[{A1,A2,…,An},{B1,B2,…,Bn}])例如:

Input: [{a,5},{2,x},{r,r}]

Output: [{a,2,r},{5,x,r}]

问题是如果我这样做:

conn = fetch_query_params(conn)
%{ "A" => input } = conn.query_params

然后输入变量是位串,所以我尝试使用 input_parsed = :binary.bin_to_list input,但是如果我尝试像这样迭代它:

output = Enum.map(input_parsed, fn {x, y} -> {x+y} end)

我收到以下错误:

(FunctionClauseError) no function clause matching in anonymous fn/1 in PwZadanie1.Router.do_match/4
        (pw_zadanie_1 0.1.0) lib/pw_zadanie1/router.ex:30: anonymous fn(91) in PwZadanie1.Router.do_match/4
        (elixir 1.11.3) lib/enum.ex:1411: Enum."-map/2-lists^map/1-0-"/2

91 在 ASCII 中是 [,所以它仍然没有被解析。

我是 Elixir 的新手,非常感谢对此的任何帮助。谢谢。

:binary.bin_to_list 不会在这里帮助你。如果你有一个像 [{1,2},{3,4}] 这样的二进制文件,那么你需要 解析 来创建它所代表的元组列表。 :binary.bin_to_list 只是给你一个与字符串中的字节相对应的字节列表(如你所见,91 是第一个)。 :binary.bin_to_list 不会尝试理解字符串的 elixir 或 erlang 语义。

传输此数据(语义完整)的行业标准方法是 JSON 并且当 JSON 需要进入查询参数或(或其他格式敏感字段,如HTTP header),一般会进行base64编码。

理想情况下,您可以更改前端以生成数据的 base64 编码 json 表示并将其放入查询参数中。然后在后端只需使用 JSON 解析器将其扩展回元组列表。如果前端是不可更改的,那么就需要自己解析查询参数。如果它始终是一个标量元组数组,那么您可以自己解析它。

从技术上讲,您可以将此字符串放入 Code.eval_string (docs),但是 请不要 使用不受信任的输入(例如查询参数)来执行此操作。但仅供 说明之用 您可以看到,对于此示例,输入 Code.eval_string 将 return 您要查找的列表。

一个更安全的选择是Code.string_to_quoted,它会编译你给它的字符串,但不会执行它。

iex(1)> Code.string_to_quoted("[{\"a\",5}, {\"b\", 4}]")
{:ok, [{"a", 5}, {"b", 4}]}