【问题标题】:How to Convert a list of tuples into a Json string如何将元组列表转换为 Json 字符串
【发布时间】:2018-01-30 17:27:50
【问题描述】:

我有一个 Erlang 元组列表如下:

[  {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]}  , 
   {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}  ]

我想要这个形式的元组列表:

<<" [  {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]} , 
       {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}] ">>

所以我尝试在 erlang 中使用 JSON 解析库(包括 jiffy 和 jsx ) 这是我所做的:

A=[  {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]}  , 
       {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}  ],

B=erlang:iolist_to_binary(io_lib:write(A)),

jsx:encode(B).

我得到以下输出(这里我将列表更改为二进制,因为 jsx 接受二进制):

 <<"[{{[97]},[2],[{3,[98]},{4,[99]}],[5,[100]],[1,1],{e},[[102]]},{{[103]},
 [3],[{6,[104]},{7,[105]}],[{8,[106]}],[1,1,1],{k},[[76]]}]">>

jiffy:encode(B) 也给出相同的输出。 谁能帮我得到输出:

<<" [  {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]} , 
           {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}] ">>

而不是

<<"[{{[97]},[2],[{3,[98]},{4,[99]}],[5,[100]],[1,1],{e},[[102]]},{{[103]},
     [3],[{6,[104]},{7,[105]}],[{8,[106]}],[1,1,1],{k},[[76]]}]">>

提前谢谢你

【问题讨论】:

    标签: json erlang jsx erlang-shell jiffy


    【解决方案1】:

    使用io_lib:format("~p", [A]) 代替io_lib:write(A)。它试图猜测哪些列表实际上是字符串。 (在 Erlang 中,字符串实际上是整数列表。试试看:"A" == [65])

    > A=[  {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]}  ,
           {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}  ].
    [{{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]},
     {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}]
    > B = erlang:iolist_to_binary(io_lib:format("~p", [A])).
    <<"[{{\"a\"},[2],[{3,\"b\"},{4,\"c\"}],[5,\"d\"],[1,1],{e},[\"f\"]},\n {{\"g\"},[3],[{6,\"h\"},{7,\"i\"}],[{8,\"j\"}],[1,1,1],{k},[\"L\"]}]">>
    

    如果您不想在双引号前看到反斜杠,可以将字符串打印到标准输出:

    > io:format("~s\n", [B]).
    [{{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]},
     {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}]
    

    【讨论】:

    • 感谢您的回复。对不起,我误解了你的回答。现在我了解到您建议单独使用 io:format("~s\n",[B]) 。但目前我得到的输出类似于 >.有什么方法可以在没有斜杠的情况下获取数据,而是像 > 这样的二进制字符串。使用 io:format("~s\n") 的选项也删除了 >,但我也想要它。我也想摆脱正在生成的'\n'。请提出一些建议
    • 要获得不带\n 的字符串,您可以执行io_lib:format("~1000p", [A]) 之类的操作 - 只有在输出长度超过 1000 个字符时才会添加换行符;不确定是否有没有限制的方法。您可以使用io:format("&lt;&lt;\"~s\"&gt;&gt;\n", [B]) 打印它以获得&lt;&lt;" 和"&gt;&gt; 标记,而无需转义中间的双引号。
    • 谢谢@legiscia,目前使用限制有效。
    【解决方案2】:

    <<" [ {{"a"},[2],[{3,"b"},{4,"c"}],[5,"d"],[1,1],{e},["f"]} , {{"g"},[3],[{6,"h"},{7,"i"}],[{8,"j"}],[1,1,1],{k},["L"]}] ">>

    这个 ^^ 不是一个有效的 erlang 术语,但我认为你得到的是你想要像 "a" 这样的“listy”字符串打印出来像 "a" 而不是 [97] .不幸的是,我发现这是 Erlang 的一个严重缺点。问题是字符串文字 "a" 只是语法糖,与术语 [97] 相同,所以无论何时输出它,你都会受到“这东西是字符串还是整数列表”的变幻莫测?”我知道摆脱这种情况的最好方法是尽可能使用二进制文件作为字符串,例如 &lt;&lt;"a"&gt;&gt; 而不是 "a"。

    【讨论】:

    • 是的@Ryan Stewart 这个词是我的自定义要求。感谢您的宝贵建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多