Как преобразовать список кортежей в строку 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: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]]}]">>

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


person abhishek ranjan    schedule 22.08.2017    source источник


Ответы (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"]}]
person legoscia    schedule 22.08.2017
comment
Спасибо за ваш ответ. Извините, я неправильно понял ваш ответ. Теперь я понял, что вы предложили использовать 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', которые генерируются. Пожалуйста, предложите что-нибудь - person abhishek ranjan; 22.08.2017
comment
Чтобы получить строку без \n, вы можете сделать что-то вроде io_lib:format("~1000p", [A]) — это добавит новые строки только в том случае, если вывод длиннее 1000 символов; не уверен, что есть способ сделать это без ограничений. Вы можете напечатать его с помощью io:format("<<\"~s\">>\n", [B]), чтобы получить маркеры <<" и ">>, не выходя из двойных кавычек в середине. - person legoscia; 22.08.2017
comment
спасибо @legiscia, использование лимита на данный момент работает. - person abhishek ranjan; 23.08.2017

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

person Ryan Stewart    schedule 22.08.2017
comment
Да @Ryan Stewart, этот термин является моим индивидуальным требованием. Спасибо за ваше ценное предложение. - person abhishek ranjan; 23.08.2017