Как преобразовать список кортежей в строку Json

У меня есть список кортежей 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"]}] ">>

Поэтому я попытался использовать библиотеки синтаксического анализа JSON в erlang (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: кодировать (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]]}]">>

заранее спасибо

2 ответа

Решение

Вместо io_lib:write(A)использовать io_lib:format("~p", [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"]}]

<<" [ {{"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" распечатываться как "a" вместо [97], К сожалению, я обнаружил, что это серьезный недостаток Эрланга. Проблема в том, что строковый литерал "a" является только синтаксическим сахаром и идентичен термину [97], так что каждый раз, когда вы выводите его, вы подвержены капризам "является ли эта вещь строкой или списком целых чисел?" Лучший способ, который я знаю, - это использовать бинарные файлы в качестве строк, где это возможно, например, <<"a">> вместо "a",

Другие вопросы по тегам