1

Тема: AHK: Обработка переменной в формате JSON и перевод в массив

Здравствуйте, столкнулся с такой проблемой, не знаю как правильно перевести переменную в формате JSON в массив. То есть все должно выглядеть как-то так.
Пусть json будет переменной содержащей в себе JSON текст, а data пустой массив.

json:= "{hello:'world',its:{over:9000},foo:['bar','lol']}"

Мне нужно как-то этот ответ перевести в массив, чтобы он выглядел примерно вот-так.

data[hello] = world
data[its][over] = 9000
data[foo][0] = bar
data[foo][1] = lol

Так же, может кому пригодиться, нашел один из примеров обработки json ответа.

+ открыть спойлер
jsonAHK(s){
    static o:=comobjcreate("scriptcontrol")
    o.language:="jscript"
    return o.eval("(" s ")")
}
jsonBuild(j) { 
    for x,y in j
        s.=((a:=(j.setcapacity(0)=(j.maxindex()-j.minindex()+1)))?"":x ":")(isobject(y)?jsonBuild(y):y/y||y==0?y:"'" y "'") ","    
        ;s.=x ":" (isobject(y)?jsonBuild(y):y/y||y==0?y:"'" y "'") ","
    return (a?"[" rtrim(s,",") "]":"{" rtrim(s,",") "}")
    ;return ("{" rtrim(s,",") "}")
}
jsonGet(s,k){
    static o:=comobjcreate("scriptcontrol")
    o.language:="jscript"
    return o.eval("(" s ")." k)
}

string := "{hello:'world',its:{over:9000},foo:['bar']}"

msgbox,% jsonGet(string,"hello")
msgbox,% jsonGet(string,"its.over")
msgbox,% jsonGet(string,"foo[0]")
ExitApp

2 (изменено: teadrinker, 2015-09-24 21:21:52)

Re: AHK: Обработка переменной в формате JSON и перевод в массив

tuma4ok пишет:

не знаю как правильно перевести переменную в формате JSON в массив

tuma4ok пишет:

нашел один из примеров обработки json ответа

Осталось совместить одно с другим:

string := "{hello:'world',its:{over:9000},foo:['bar']}"

oJSON := jsonAHK(string)
MsgBox, % oJSON.hello "`n" oJSON.its.over "`n" oJSON.foo.0

jsonAHK(s){
    static o:=comobjcreate("scriptcontrol")
    o.language:="jscript"
    return o.eval("(" s ")")
}

Но так работать будет только под AHK x32, т. к. com-объект ScriptControl существует только в 32-битной версии. Кроме того, так мы получаем не AHK-объект, его ключи нельзя перебирать с помощью for. Вариант без этих недостатков:

json := "{hello:'world',its:{over:9000},foo:['bar','lol']}"

obj := GetObjectFromJsonString(json)

MsgBox, % obj.hello "`n" obj.its.over "`n" obj.foo[1] "`n" obj.foo[2]

GetObjectFromJsonString(JsonString)
{
   JS := GetObjJScript()
   AddMethods(JS)
   try oJSON := JS.eval("(" JsonString ")")
   catch  {
      MsgBox, Неверный формат JsonString
      Return
   }
   Return CreateObject(oJSON)
}
   
GetObjJScript()
{
   if !FileExist(ComObjFile := A_ScriptDir "\JS.wsc")
      FileAppend,
         (LTrim
            <component>
            <public><method name='eval'/></public>
            <script language='JScript'></script>
            </component>
         ), % ComObjFile
   Return ComObjGet("script:" . ComObjFile)
}

AddMethods(ByRef JS)
{
   JScript =
   (
      Object.prototype.GetKeys = function () {
         var keys = []
         for (var k in this)
            if (this.hasOwnProperty(k))
               keys.push(k)
         return keys
      }
      Object.prototype.IsArray = function () {
         var toStandardString = {}.toString
         return toStandardString.call(this) == '[object Array]'
      }
   )
   JS.eval("delete ActiveXObject; delete GetObject;")
   JS.eval(JScript)
}

CreateObject(ObjJS)
{
   res := ObjJS.IsArray()
   if (res = "")
      Return ObjJS
   
   else if (res = -1)  {
      obj := []
      Loop % ObjJS.length
         obj[A_Index] := CreateObject(ObjJS[A_Index - 1])
   }
   else if (res = 0)  {
      keys := ObjJS.GetKeys()
      obj := {}
      Loop % keys.length
         k := keys[A_Index - 1], obj[k] := CreateObject(ObjJS[k])
   }
   Return obj
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Обработка переменной в формате JSON и перевод в массив

Хм.. Все кажется идет хорошо, но можно ли как-то сделать так чтобы если указан неполный путь до параметра, то отображались все его вложенные?
Вот та же строка из кода:

json := "{hello:'world',its:{over:9000},foo:['bar','lol']}"

В foo хранится 2 значения, это bar и lol.
Мне нужно чтобы при таком коде:

MsgBox, % obj.foo

Вывелся вот такой ответ:

['bar','lol']

4

Re: AHK: Обработка переменной в формате JSON и перевод в массив

tuma4ok пишет:

если указан неполный путь до параметра, то отображались все его вложенные?

А если вложенные тоже окажутся объектами? Или среди вложенных будут и строки, и объекты вместе?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Обработка переменной в формате JSON и перевод в массив

А почему бы не воспользоваться готовой библиотекой?

6

Re: AHK: Обработка переменной в формате JSON и перевод в массив

А она чем-то лучше, чем мой вариант?
Не думаю, это просто парсинг строки.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder