如何将元组列表转换为Json字符串

3

我有一个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]]}]">>

Thank you in advance

2个回答

3

使用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])。但是目前我得到的输出结果是这样的<< "[{{"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")选项也会删除<<" ">>,但我也想要它。另外,我也想摆脱生成的'\n'。请给予建议。 - abhishek ranjan
要获取没有\n的字符串,您可以执行类似于io_lib:format("~1000p", [A])的操作 - 如果输出长度超过1000个字符,则只会添加换行符;不确定是否有一种方法可以在没有限制的情况下完成它。您可以使用io:format("<<\"~s\">>\n", [B])打印它,以获取中间双引号的<<"">>标记而不转义它们。 - legoscia
谢谢@legiscia,目前使用限制已经起作用了。 - abhishek ranjan

3

<<" [ {{"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]完全相同,因此每次输出它时,您都会受到"这个东西是字符串还是整数列表?"的影响。我所知道的最好方法是尽可能以二进制形式使用字符串,例如使用<<"a">>而不是"a"


是的,@Ryan Stewart,这个术语是我的定制要求。感谢您宝贵的建议。 - abhishek ranjan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接