Тема: AHK: Помогите переписать JSON_Stringify
Добрейшего всем, хочу реализовать подобие JSON.stringify() у JavaScript. Там есть такая крутая возможность - указать space, которое будет делать отступы.
Есть JSON строка:
{"Accept-Ranges": ["bytes"], "Alt-Svc": ["quic=\":443\"", "ma=2592000", "v=\"43,46\", h3-Q043=\":443\"", "ma=2592000, h3-Q046=\":443\"", "ma=2592000, h3-Q050=\":443\"", "ma=2592000, h3-25=\":443\"", "ma=2592000, h3-27=\":443\"", "ma=2592000"], "Connection": ["keep-alive"], "Content-Length": ["4433"], "Content-Type": ["text/html"], "Date": ["Thu, 06 May 2021 06:16:13 GMT"], "Keep-Alive": ["timeout=60"], "Last-Modified": ["Thu, 04 Mar 2021 14:43:58 GMT"], "Server": ["ddos-guard"], "Set-Cookie": ["__ddg1=xBGnCJjM7HmST7hYgF6j", "Domain=.test.com", "HttpOnly", "Path=/", "Expires=Fri, 06-May-2022 06:16:13 GMT"], "Vary": ["User-Agent"], "X-Turbo-Charged-By": ["LiteSpeed"]}
И нужно получить вот такое:
{
"Accept-Ranges":
[
"bytes"
],
"Alt-Svc":
[
"quic=\":443\"",
"ma=2592000",
"v=\"43,46\", h3-Q043=\":443\"",
"ma=2592000, h3-Q046=\":443\"",
"ma=2592000, h3-Q050=\":443\"",
"ma=2592000, h3-25=\":443\"",
"ma=2592000, h3-27=\":443\"",
"ma=2592000"
],
"Connection":
[
"keep-alive"
],
"Content-Length":
[
"4433"
],
"Content-Type":
[
"text/html"
],
"Date":
[
"Thu, 06 May 2021 06:16:13 GMT"
],
"Keep-Alive":
[
"timeout=60"
],
"Last-Modified":
[
"Thu, 04 Mar 2021 14:43:58 GMT"
],
"Server":
[
"ddos-guard"
],
"Set-Cookie":
[
"__ddg1=xBGnCJjM7HmST7hYgF6j",
"Domain=.test.com",
"HttpOnly",
"Path=/",
"Expires=Fri, 06-May-2022 06:16:13 GMT"
],
"Vary":
[
"User-Agent"
],
"X-Turbo-Charged-By":
[
"LiteSpeed"
]
}
Мои попытки:
class JSON
{
Decode(jsonStr)
{
SC := ComObjCreate("ScriptControl")
SC.Language := "JScript"
ComObjError(false)
jsCode =
(
function arrangeForAhkTraversing(obj){
if(obj instanceof Array){
for(var i=0 ; i<obj.length ; ++i)
obj[i] = arrangeForAhkTraversing(obj[i]) ;
return ['array',obj] ;
}else if(obj instanceof Object){
var keys = [], values = [] ;
for(var key in obj){
keys.push(key) ;
values.push(arrangeForAhkTraversing(obj[key])) ;
}
return ['object',[keys,values]] ;
}else
return [typeof obj,obj] ;
}
)
SC.ExecuteStatement(jsCode "; obj=" jsonStr)
return this.convertJScriptObjToAhks( SC.Eval("arrangeForAhkTraversing(obj)") )
}
convertJScriptObjToAhks(jsObj)
{
if (jsObj[0]="object")
{
obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
loop % keys.length
obj[keys[A_INDEX-1]] := this.convertJScriptObjToAhks( values[A_INDEX-1] )
return obj
}
else if (jsObj[0]="array")
{
array := []
loop % jsObj[1].length
array.insert(this.convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
return array
}
else
return jsObj[1]
}
Stringify(value, space := 0, _indent := 1)
{
_space := space
if (space ~= "^\d+$")
{
_space := strRepeat(A_Space, space)
}
str := ""
array := true
for k in value
{
if (k == A_Index)
{
continue
}
array := false
break
}
indent := _indent
for a, b in value
{
if (space)
{
str .= strRepeat(_space, indent)
}
str .= (array ? "" : """" a """: ")
if (IsObject(b))
{
if (space)
{
str := RTrim(str, " ") "`n" strRepeat(_space, indent)
}
str .= this.Stringify(b, space, indent + 1)
}
else
{
str .= """" StrReplace(b, """", "\""") """"
}
str .= "," (space ? "`n" : " ")
}
str := RTrim(str, " ,`n")
str := RegExReplace(str, "`n([\s]+)?`n", "`n")
indent--
out := (array ? "[" : "{") (space ? "`n" : "") str (space ? "`n" : "")
out .= (space ? strRepeat(_space, indent) : "") (array ? "]" : "}")
return out
}
}
Доп. функции которые использовались в функциии:
strRepeat(str, count)
{
return StrReplace(Format("{:" count "}", ""), " ", str)
}
objectMerge(target, sources*)
{
target := clone(target)
for i, arr in sources
{
for key, value in arr
{
target[key] := (IsObject(value) && !value.base.IsArray) ? ObjectMerge(value, target[key]) : value
}
}
return target
}
clone(obj)
{
cloned := obj.clone()
for i, key in obj
{
if IsObject(key)
{
cloned[i] := clone(key)
}
}
return cloned
}
Использование:
jsonString = {"Accept-Ranges": ["bytes"], "Alt-Svc": ["quic=\":443\"", "ma=2592000", "v=\"43,46\", h3-Q043=\":443\"", "ma=2592000, h3-Q046=\":443\"", "ma=2592000, h3-Q050=\":443\"", "ma=2592000, h3-25=\":443\"", "ma=2592000, h3-27=\":443\"", "ma=2592000"], "Connection": ["keep-alive"], "Content-Length": ["4433"], "Content-Type": ["text/html"], "Date": ["Thu, 06 May 2021 06:16:13 GMT"], "Keep-Alive": ["timeout=60"], "Last-Modified": ["Thu, 04 Mar 2021 14:43:58 GMT"], "Server": ["ddos-guard"], "Set-Cookie": ["__ddg1=xBGnCJjM7HmST7hYgF6j", "Domain=.test.com", "HttpOnly", "Path=/", "Expires=Fri, 06-May-2022 06:16:13 GMT"], "Vary": ["User-Agent"], "X-Turbo-Charged-By": ["LiteSpeed"]}
test1 := JSON.Decode(jsonString)
test2 := {key1: 1, key2: 2, key3: ["val1", "val2"], tupac: ["Shakur", {"test": 1, tupac: ["Shakur", {"test": 1}]}]}
msgbox, % JSON.Stringify(test1) ; (1) Все в одну строку
msgbox, % JSON.Stringify(test1, "`t") ; (2) С табуляцией
msgbox, % JSON.Stringify(test1, 2) ; (3) С двумя пробелами
msgbox, % JSON.Stringify(test2) ; ;(4) Все в одну строку
msgbox, % JSON.Stringify(test2, "`t") ; (5) С табуляцией
msgbox, % JSON.Stringify(test2, 2) ; (6) С двумя пробелами
{"Accept-Ranges": ["bytes"], "Alt-Svc": ["quic=\":443\"", "ma=2592000", "v=\"43,46\", h3-Q043=\":443\"", "ma=2592000, h3-Q046=\":443\"", "ma=2592000, h3-Q050=\":443\"", "ma=2592000, h3-25=\":443\"", "ma=2592000, h3-27=\":443\"", "ma=2592000"], "Connection": ["keep-alive"], "Content-Length": ["4433"], "Content-Type": ["text/html"], "Date": ["Thu, 06 May 2021 06:16:13 GMT"], "Keep-Alive": ["timeout=60"], "Last-Modified": ["Thu, 04 Mar 2021 14:43:58 GMT"], "Server": ["ddos-guard"], "Set-Cookie": ["__ddg1=xBGnCJjM7HmST7hYgF6j", "Domain=.test.com", "HttpOnly", "Path=/", "Expires=Fri, 06-May-2022 06:16:13 GMT"], "Vary": ["User-Agent"], "X-Turbo-Charged-By": ["LiteSpeed"]}
{
"Accept-Ranges":
[
"bytes"
],
"Alt-Svc":
[
"quic=\":443\"",
"ma=2592000",
"v=\"43,46\", h3-Q043=\":443\"",
"ma=2592000, h3-Q046=\":443\"",
"ma=2592000, h3-Q050=\":443\"",
"ma=2592000, h3-25=\":443\"",
"ma=2592000, h3-27=\":443\"",
"ma=2592000"
],
"Connection":
[
"keep-alive"
],
"Content-Length":
[
"4433"
],
"Content-Type":
[
"text/html"
],
"Date":
[
"Thu, 06 May 2021 06:16:13 GMT"
],
"Keep-Alive":
[
"timeout=60"
],
"Last-Modified":
[
"Thu, 04 Mar 2021 14:43:58 GMT"
],
"Server":
[
"ddos-guard"
],
"Set-Cookie":
[
"__ddg1=xBGnCJjM7HmST7hYgF6j",
"Domain=.test.com",
"HttpOnly",
"Path=/",
"Expires=Fri, 06-May-2022 06:16:13 GMT"
],
"Vary":
[
"User-Agent"
],
"X-Turbo-Charged-By":
[
"LiteSpeed"
]
}
{
"Accept-Ranges":
[
"bytes"
],
"Alt-Svc":
[
"quic=\":443\"",
"ma=2592000",
"v=\"43,46\", h3-Q043=\":443\"",
"ma=2592000, h3-Q046=\":443\"",
"ma=2592000, h3-Q050=\":443\"",
"ma=2592000, h3-25=\":443\"",
"ma=2592000, h3-27=\":443\"",
"ma=2592000"
],
"Connection":
[
"keep-alive"
],
"Content-Length":
[
"4433"
],
"Content-Type":
[
"text/html"
],
"Date":
[
"Thu, 06 May 2021 06:16:13 GMT"
],
"Keep-Alive":
[
"timeout=60"
],
"Last-Modified":
[
"Thu, 04 Mar 2021 14:43:58 GMT"
],
"Server":
[
"ddos-guard"
],
"Set-Cookie":
[
"__ddg1=xBGnCJjM7HmST7hYgF6j",
"Domain=.test.com",
"HttpOnly",
"Path=/",
"Expires=Fri, 06-May-2022 06:16:13 GMT"
],
"Vary":
[
"User-Agent"
],
"X-Turbo-Charged-By":
[
"LiteSpeed"
]
}
{"key1": "1", "key2": "2", "key3": ["val1", "val2"], "tupac": ["Shakur", {"test": "1", "tupac": ["Shakur", {"test": "1"}]}]}
{
"key1": "1",
"key2": "2",
"key3":
[
"val1",
"val2"
],
"tupac":
[
"Shakur",
{
"test": "1",
"tupac":
[
"Shakur",
{
"test": "1"
}
]
}
]
}
{
"key1": "1",
"key2": "2",
"key3":
[
"val1",
"val2"
],
"tupac":
[
"Shakur",
{
"test": "1",
"tupac":
[
"Shakur",
{
"test": "1"
}
]
}
]
}
Мне не нравится мой код метод Stringify класса JSON, слишком все костыльно сделано, что можно придумать?