【问题标题】:Elixir: accessing a list of tuples from query_param and iterating over itElixir:从 query_param 访问元组列表并对其进行迭代
【发布时间】:2021-04-11 11:29:44
【问题描述】:

我通过如下查询参数获取输入: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 的新手,如果能提供任何帮助,我将不胜感激。谢谢。

【问题讨论】:

  • 请在此处发布input
  • 我更新了帖子。
  • 您能发一个input 位串吗?以及期望的结果。
  • 位串输入是"[{1,a},{2,3}]"(来自conn.query_params),期望的结果是以下元组列表:[{1,2}, {a,3}]
  • 这听起来至少部分是 HTML 编码的问题...如果您可以控制输入,为什么不将 URL 中的输入作为 JSON 编码的字符串传递?

标签: elixir cowboy


【解决方案1】:

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

传输此数据(语义完整)的行业标准方式是 JSON,当 JSON 需要进入查询参数或(或其他格式敏感字段,如 HTTP 标头)时,通常会采用 base64 编码.

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多