Need help about Associative Arrays

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Bral
Posts: 20
Joined: 04 Apr 2015, 21:24

Need help about Associative Arrays

03 Jan 2018, 04:10

This code return right data:

Test := {"name":"Baal","age":"50"}
MsgBox % Test.name "age" Test.age

I have some data is like this {"name":"Baal","age":"50"} ,this data in a Variables named DATA. but this code can't return right data:

DATA := "{""name"":""Baal"",""age"":""50""}"
Test := DATA
MsgBox % Test.name "age" Test.age

what wrong? how to convert my data to Associative Arrays
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Need help about Associative Arrays

03 Jan 2018, 04:54

Try this:

Code: Select all

DATA := {name: "Baal", age: 50}
Test := DATA
MsgBox % Test.name " age " Test.age
I hope that helps.
teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Need help about Associative Arrays

03 Jan 2018, 05:16

Bral wrote:I have some data is like this {"name":"Baal","age":"50"} ,this data in a Variables named DATA.
Since your data is in proper JSON format, you could using any JSON parsing code to convert such string to an AHK object. One of the approaches is using JScript for this purpose.

Code: Select all

DATA := "{""name"":""Baal"",""age"":""50""}"
Test := JSON.Parse(DATA)

MsgBox, % Test.name . "`n" . Test.age

class JSON
{
   static JS := JSON._GetJScripObject()
   
   Parse(JsonString)  {
      try oJSON := this.JS.("(" JsonString ")")
      catch  {
         MsgBox, Wrong JsonString!
         Return
      }
      Return this._CreateObject(oJSON)
   }

   _GetJScripObject()  {
      VarSetCapacity(tmpFile, (MAX_PATH := 260) << !!A_IsUnicode, 0)
      DllCall("GetTempFileName", Str, A_Temp, Str, "AHK", UInt, 0, Str, tmpFile)
      
      FileAppend,
      (
      <component>
      <public><method name='eval'/></public>
      <script language='JScript'></script>
      </component>
      ), % tmpFile
      
      JS := ObjBindMethod( ComObjGet("script:" . tmpFile), "eval" )
      FileDelete, % tmpFile
      JSON._AddMethods(JS)
      Return JS
   }

   _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.("delete ActiveXObject; delete GetObject;")
      JS.(JScript)
   }

   _CreateObject(ObjJS)  {
      res := ObjJS.IsArray()
      if (res = "")
         Return ObjJS
      
      else if (res = -1)  {
         obj := []
         Loop % ObjJS.length
            obj[A_Index] := this._CreateObject(ObjJS[A_Index - 1])
      }
      else if (res = 0)  {
         obj := {}
         keys := ObjJS.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(ObjJS[k])
      }
      Return obj
   }
}
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: Need help about Associative Arrays

03 Jan 2018, 19:23

teadrinker wrote:
Bral wrote:I have some data is like this {"name":"Baal","age":"50"} ,this data in a Variables named DATA.
Since your data is in proper JSON format, you could using any JSON parsing code to convert such string to an AHK object. One of the approaches is using JScript for this purpose.
Full fledge JSON parsing is nice but if you just need a simple solution for a specific case then you can use a simple function like this:

Code: Select all

DATA := "{""name"":""Baal"",""age"":""50""}"
Test := JSON_SimpleDumbConversion(DATA)
MsgBox % Test.name " age " Test.age

JSON_SimpleDumbConversion(str)
{
	arr := {}
	for index, element in StrSplit(RegExReplace(str, "{|}|"""), ",")
		z := StrSplit(element, ":"), arr[z.1] := z.2
	return arr
}
It is basically just slicing and dicing by commas and colons to build a simple associative array while striping unneeded "{}.

I have used cocobelgica's JSON parsing to great effect when you need the full power it brings, especially its reviver function ability.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Need help about Associative Arrays

04 Jan 2018, 12:44

FanaticGuru wrote:if you just need a simple solution for a specific case
Yes, sometimes this can work. :)
Bral
Posts: 20
Joined: 04 Apr 2015, 21:24

Re: Need help about Associative Arrays

04 Jan 2018, 19:19

Thanks for teadrinker and FanaticGuru, your code works fine. but cocobelgica's AutoHotkey-JSON can't work -___-
teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Need help about Associative Arrays

04 Jan 2018, 20:12

Bral wrote:cocobelgica's AutoHotkey-JSON can't work
For me it works like this:

Code: Select all

DATA := "{""name"":""Baal"",""age"":""50""}"
Test := JSON.Load(DATA)
MsgBox, % Test.name . "`n" . Test.age

/**
 * Lib: JSON.ahk
 *     JSON lib for AutoHotkey.
 * Version:
 *     v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)]
 * License:
 *     WTFPL [http://wtfpl.net/]
 * Requirements:
 *     Latest version of AutoHotkey (v1.1+ or v2.0-a+)
 * Installation:
 *     Use #Include JSON.ahk or copy into a function library folder and then
 *     use #Include <JSON>
 * Links:
 *     GitHub:     - https://github.com/cocobelgica/AutoHotkey-JSON
 *     Forum Topic - http://goo.gl/r0zI8t
 *     Email:      - cocobelgica <at> gmail <dot> com
 */


/**
 * Class: JSON
 *     The JSON object contains methods for parsing JSON and converting values
 *     to JSON. Callable - NO; Instantiable - YES; Subclassable - YES;
 *     Nestable(via #Include) - NO.
 * Methods:
 *     Load() - see relevant documentation before method definition header
 *     Dump() - see relevant documentation before method definition header
 */
class JSON
{
   /**
    * Method: Load
    *     Parses a JSON string into an AHK value
    * Syntax:
    *     value := JSON.Load( text [, reviver ] )
    * Parameter(s):
    *     value      [retval] - parsed value
    *     text    [in, ByRef] - JSON formatted string
    *     reviver   [in, opt] - function object, similar to JavaScript's
    *                           JSON.parse() 'reviver' parameter
    */
   class Load extends JSON.Functor
   {
      Call(self, ByRef text, reviver:="")
      {
         this.rev := IsObject(reviver) ? reviver : false
      ; Object keys(and array indices) are temporarily stored in arrays so that
      ; we can enumerate them in the order they appear in the document/text instead
      ; of alphabetically. Skip if no reviver function is specified.
         this.keys := this.rev ? {} : false

         static quot := Chr(34), bashq := "\" . quot
              , json_value := quot . "{[01234567890-tfn"
              , json_value_or_array_closing := quot . "{[]01234567890-tfn"
              , object_key_or_object_closing := quot . "}"

         key := ""
         is_key := false
         root := {}
         stack := [root]
         next := json_value
         pos := 0

         while ((ch := SubStr(text, ++pos, 1)) != "") {
            if InStr(" `t`r`n", ch)
               continue
            if !InStr(next, ch, 1)
               this.ParseError(next, text, pos)

            holder := stack[1]
            is_array := holder.IsArray

            if InStr(",:", ch) {
               next := (is_key := !is_array && ch == ",") ? quot : json_value

            } else if InStr("}]", ch) {
               ObjRemoveAt(stack, 1)
               next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}"

            } else {
               if InStr("{[", ch) {
               ; Check if Array() is overridden and if its return value has
               ; the 'IsArray' property. If so, Array() will be called normally,
               ; otherwise, use a custom base object for arrays
                  static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0
               
               ; sacrifice readability for minor(actually negligible) performance gain
                  (ch == "{")
                     ? ( is_key := true
                       , value := {}
                       , next := object_key_or_object_closing )
                  ; ch == "["
                     : ( value := json_array ? new json_array : []
                       , next := json_value_or_array_closing )
                  
                  ObjInsertAt(stack, 1, value)

                  if (this.keys)
                     this.keys[value] := []
               
               } else {
                  if (ch == quot) {
                     i := pos
                     while (i := InStr(text, quot,, i+1)) {
                        value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c")

                        static tail := A_AhkVersion<"2" ? 0 : -1
                        if (SubStr(value, tail) != "\")
                           break
                     }

                     if (!i)
                        this.ParseError("'", text, pos)

                       value := StrReplace(value,  "\/",  "/")
                     , value := StrReplace(value, bashq, quot)
                     , value := StrReplace(value,  "\b", "`b")
                     , value := StrReplace(value,  "\f", "`f")
                     , value := StrReplace(value,  "\n", "`n")
                     , value := StrReplace(value,  "\r", "`r")
                     , value := StrReplace(value,  "\t", "`t")

                     pos := i ; update pos
                     
                     i := 0
                     while (i := InStr(value, "\",, i+1)) {
                        if !(SubStr(value, i+1, 1) == "u")
                           this.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))

                        uffff := Abs("0x" . SubStr(value, i+2, 4))
                        if (A_IsUnicode || uffff < 0x100)
                           value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
                     }

                     if (is_key) {
                        key := value, next := ":"
                        continue
                     }
                  
                  } else {
                     value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos)

                     static number := "number", integer :="integer"
                     if value is %number%
                     {
                        if value is %integer%
                           value += 0
                     }
                     else if (value == "true" || value == "false")
                        value := %value% + 0
                     else if (value == "null")
                        value := ""
                     else
                     ; we can do more here to pinpoint the actual culprit
                     ; but that's just too much extra work.
                        this.ParseError(next, text, pos, i)

                     pos += i-1
                  }

                  next := holder==root ? "" : is_array ? ",]" : ",}"
               } ; If InStr("{[", ch) { ... } else

               is_array? key := ObjPush(holder, value) : holder[key] := value

               if (this.keys && this.keys.HasKey(holder))
                  this.keys[holder].Push(key)
            }
         
         } ; while ( ... )

         return this.rev ? this.Walk(root, "") : root[""]
      }

      ParseError(expect, ByRef text, pos, len:=1)
      {
         static quot := Chr(34), qurly := quot . "}"
         
         line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length()
         col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1))
         msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}"
         ,     (expect == "")     ? "Extra data"
             : (expect == "'")    ? "Unterminated string starting at"
             : (expect == "\")    ? "Invalid \escape"
             : (expect == ":")    ? "Expecting ':' delimiter"
             : (expect == quot)   ? "Expecting object key enclosed in double quotes"
             : (expect == qurly)  ? "Expecting object key enclosed in double quotes or object closing '}'"
             : (expect == ",}")   ? "Expecting ',' delimiter or object closing '}'"
             : (expect == ",]")   ? "Expecting ',' delimiter or array closing ']'"
             : InStr(expect, "]") ? "Expecting JSON value or array closing ']'"
             :                      "Expecting JSON value(string, number, true, false, null, object or array)"
         , line, col, pos)

         static offset := A_AhkVersion<"2" ? -3 : -4
         throw Exception(msg, offset, SubStr(text, pos, len))
      }

      Walk(holder, key)
      {
         value := holder[key]
         if IsObject(value) {
            for i, k in this.keys[value] {
               ; check if ObjHasKey(value, k) ??
               v := this.Walk(value, k)
               if (v != JSON.Undefined)
                  value[k] := v
               else
                  ObjDelete(value, k)
            }
         }
         
         return this.rev.Call(holder, key, value)
      }
   }

   /**
    * Method: Dump
    *     Converts an AHK value into a JSON string
    * Syntax:
    *     str := JSON.Dump( value [, replacer, space ] )
    * Parameter(s):
    *     str        [retval] - JSON representation of an AHK value
    *     value          [in] - any value(object, string, number)
    *     replacer  [in, opt] - function object, similar to JavaScript's
    *                           JSON.stringify() 'replacer' parameter
    *     space     [in, opt] - similar to JavaScript's JSON.stringify()
    *                           'space' parameter
    */
   class Dump extends JSON.Functor
   {
      Call(self, value, replacer:="", space:="")
      {
         this.rep := IsObject(replacer) ? replacer : ""

         this.gap := ""
         if (space) {
            static integer := "integer"
            if space is %integer%
               Loop, % ((n := Abs(space))>10 ? 10 : n)
                  this.gap .= " "
            else
               this.gap := SubStr(space, 1, 10)

            this.indent := "`n"
         }

         return this.Str({"": value}, "")
      }

      Str(holder, key)
      {
         value := holder[key]

         if (this.rep)
            value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined)

         if IsObject(value) {
         ; Check object type, skip serialization for other object types such as
         ; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc.
            static type := A_AhkVersion<"2" ? "" : Func("Type")
            if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") {
               if (this.gap) {
                  stepback := this.indent
                  this.indent .= this.gap
               }

               is_array := value.IsArray
            ; Array() is not overridden, rollback to old method of
            ; identifying array-like objects. Due to the use of a for-loop
            ; sparse arrays such as '[1,,3]' are detected as objects({}). 
               if (!is_array) {
                  for i in value
                     is_array := i == A_Index
                  until !is_array
               }

               str := ""
               if (is_array) {
                  Loop, % value.Length() {
                     if (this.gap)
                        str .= this.indent
                     
                     v := this.Str(value, A_Index)
                     str .= (v != "") ? v . "," : "null,"
                  }
               } else {
                  colon := this.gap ? ": " : ":"
                  for k in value {
                     v := this.Str(value, k)
                     if (v != "") {
                        if (this.gap)
                           str .= this.indent

                        str .= this.Quote(k) . colon . v . ","
                     }
                  }
               }

               if (str != "") {
                  str := RTrim(str, ",")
                  if (this.gap)
                     str .= stepback
               }

               if (this.gap)
                  this.indent := stepback

               return is_array ? "[" . str . "]" : "{" . str . "}"
            }
         
         } else ; is_number ? value : "value"
            return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value)
      }

      Quote(string)
      {
         static quot := Chr(34), bashq := "\" . quot

         if (string != "") {
              string := StrReplace(string,  "\",  "\\")
            ; , string := StrReplace(string,  "/",  "\/") ; optional in ECMAScript
            , string := StrReplace(string, quot, bashq)
            , string := StrReplace(string, "`b",  "\b")
            , string := StrReplace(string, "`f",  "\f")
            , string := StrReplace(string, "`n",  "\n")
            , string := StrReplace(string, "`r",  "\r")
            , string := StrReplace(string, "`t",  "\t")

            static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]"
            while RegExMatch(string, rx_escapable, m)
               string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value)))
         }

         return quot . string . quot
      }
   }

   /**
    * Property: Undefined
    *     Proxy for 'undefined' type
    * Syntax:
    *     undefined := JSON.Undefined
    * Remarks:
    *     For use with reviver and replacer functions since AutoHotkey does not
    *     have an 'undefined' type. Returning blank("") or 0 won't work since these
    *     can't be distnguished from actual JSON values. This leaves us with objects.
    *     Replacer() - the caller may return a non-serializable AHK objects such as
    *     ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to
    *     mimic the behavior of returning 'undefined' in JavaScript but for the sake
    *     of code readability and convenience, it's better to do 'return JSON.Undefined'.
    *     Internally, the property returns a ComObject with the variant type of VT_EMPTY.
    */
   Undefined[]
   {
      get {
         static empty := {}, vt_empty := ComObject(0, &empty, 1)
         return vt_empty
      }
   }

   class Functor
   {
      __Call(method, ByRef arg, args*)
      {
      ; When casting to Call(), use a new instance of the "function object"
      ; so as to avoid directly storing the properties(used across sub-methods)
      ; into the "function object" itself.
         if IsObject(method)
            return (new this).Call(method, arg, args*)
         else if (method == "")
            return (new this).Call(arg, args*)
      }
   }
}
Bral
Posts: 20
Joined: 04 Apr 2015, 21:24

Re: Need help about Associative Arrays

04 Jan 2018, 20:45

#Include, JSON.ahk
try
{
Http := ComObjCreate("Microsoft.XmlHttp")
Http.Open("POST", "http://www.duanrong.com/lcjh/list/0", false)
Http.Send("size=10")
JSONS := Http.ResponseText
}
FileAppend, %JSONS%, json.txt
Test := JSON.Load(JSONS)
MsgBox % Test.response.total

I get an error: "Expecting JSON value(string, number, true, false, null, object or array)".
I think this json file have data error?
teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: Need help about Associative Arrays

04 Jan 2018, 21:47

The response text is:
{"response":{"total":55,"page":1,"exitFeeRate":0.02,"list":[{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.02000000,"code":"IPlan180104223321038","repayType":"IFPA","raiseOpenTime":"2018-01-04 22:33:21","vipRate":0.0,"newbieOnly":1,"id":2179,"availableQuota":828900.0,"planType":1,"quota":1000000.0,"term":1,"increaseInterest":2.0,"background":"#f7b528","name":"月月盈201800038","fixRate":0.08000000,"activityName":"新手专享1个月"},{"exitRate":0.02,"status":2,"bonusRate":0E-8,"code":"IPlan180104234237039","repayType":"IFPA","raiseOpenTime":"2018-01-04 23:42:37","vipRate":0.0,"newbieOnly":0,"id":2180,"availableQuota":494300.0,"planType":1,"quota":1000000.0,"term":3,"name":"月月盈201800039","fixRate":0.08400000},{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.00500000,"code":"IPlan180104192731037","repayType":"IFPA","raiseOpenTime":"2018-01-04 19:27:31","vipRate":0.0,"newbieOnly":0,"id":2178,"availableQuota":560300.0,"planType":1,"quota":1000000.0,"term":6,"increaseInterest":0.5,"background":"#f9849f","name":"月月盈201800037","fixRate":0.09000000,"activityName":"精选加息"},{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.00800000,"code":"IPlan180104161837036","repayType":"IFPA","raiseOpenTime":"2018-01-04 16:18:37","vipRate":0.0,"newbieOnly":0,"id":2177,"availableQuota":357100.0,"planType":1,"quota":1000000.0,"term":12,"increaseInterest":0.8,"background":"#f9849f","name":"月月盈201800036","fixRate":0.10500000,"activityName":"精选加息"},{"exitRate":0.02,"status":1,"bonusRate":0E-8,"code":"IPlan180105093250042","repayType":"IFPA","raiseOpenTime":"2018-01-05 10:00:00","vipRate":0.0,"newbieOnly":0,"id":2181,"availableQuota":500000.0,"planType":1,"quota":1000000.0,"term":1,"name":"月月盈201800040","fixRate":0.08000000}],"newbieUsable":20000.0,"totalPages":11,"size":5},"status":"SUCCESS","nowTime":1515117200265}
The error message is:
Line: 1
Col: 481
Char: 481

Specifically: 0E-8
As I see, in that library there is an issue with parsing of numbers in such format (0E-8). However, my code works fine:

Code: Select all

JSONS =
(
{"response":{"total":55,"page":1,"exitFeeRate":0.02,"list":[{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.02000000,"code":"IPlan180104223321038","repayType":"IFPA","raiseOpenTime":"2018-01-04 22:33:21","vipRate":0.0,"newbieOnly":1,"id":2179,"availableQuota":828900.0,"planType":1,"quota":1000000.0,"term":1,"increaseInterest":2.0,"background":"#f7b528","name":"月月盈201800038","fixRate":0.08000000,"activityName":"新手专享1个月"},{"exitRate":0.02,"status":2,"bonusRate":0E-8,"code":"IPlan180104234237039","repayType":"IFPA","raiseOpenTime":"2018-01-04 23:42:37","vipRate":0.0,"newbieOnly":0,"id":2180,"availableQuota":494300.0,"planType":1,"quota":1000000.0,"term":3,"name":"月月盈201800039","fixRate":0.08400000},{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.00500000,"code":"IPlan180104192731037","repayType":"IFPA","raiseOpenTime":"2018-01-04 19:27:31","vipRate":0.0,"newbieOnly":0,"id":2178,"availableQuota":560300.0,"planType":1,"quota":1000000.0,"term":6,"increaseInterest":0.5,"background":"#f9849f","name":"月月盈201800037","fixRate":0.09000000,"activityName":"精选加息"},{"fontColor":"#ffffff","exitRate":0.02,"status":2,"bonusRate":0.00800000,"code":"IPlan180104161837036","repayType":"IFPA","raiseOpenTime":"2018-01-04 16:18:37","vipRate":0.0,"newbieOnly":0,"id":2177,"availableQuota":357100.0,"planType":1,"quota":1000000.0,"term":12,"increaseInterest":0.8,"background":"#f9849f","name":"月月盈201800036","fixRate":0.10500000,"activityName":"精选加息"},{"exitRate":0.02,"status":1,"bonusRate":0E-8,"code":"IPlan180105093250042","repayType":"IFPA","raiseOpenTime":"2018-01-05 10:00:00","vipRate":0.0,"newbieOnly":0,"id":2181,"availableQuota":500000.0,"planType":1,"quota":1000000.0,"term":1,"name":"月月盈201800040","fixRate":0.08000000}],"newbieUsable":20000.0,"totalPages":11,"size":5},"status":"SUCCESS","nowTime":1515117200265}
)

Test := JSON.Parse(JSONS)
MsgBox % Test.response.total

class JSON
{
   static JS := JSON._GetJScripObject()
   
   Parse(JsonString)  {
      try oJSON := this.JS.("(" JsonString ")")
      catch  {
         MsgBox, Wrong JsonString!
         Return
      }
      Return this._CreateObject(oJSON)
   }
   
   GetFromUrl(url, body := "")  {
      try  {
         XmlHttp := ComObjCreate("Microsoft.XmlHttp")
         XmlHttp.Open("GET", url, false)
         XmlHttp.Send(body)
         res := XmlHttp.ResponseText
      }
      catch e  {
         MsgBox,, Microsoft.XmlHttp failed!, % "Error: " . e.message
      }
      if !e  {
         status := XmlHttp.Status
         if (status != 200)
            MsgBox,, Failed to load data!, % "Status code: " . status
         else
            Return res
      }
   }

   _GetJScripObject()  {
      VarSetCapacity(tmpFile, (MAX_PATH := 260) << !!A_IsUnicode, 0)
      DllCall("GetTempFileName", Str, A_Temp, Str, "AHK", UInt, 0, Str, tmpFile)
      
      FileAppend,
      (
      <component>
      <public><method name='eval'/></public>
      <script language='JScript'></script>
      </component>
      ), % tmpFile
      
      JS := ObjBindMethod( ComObjGet("script:" . tmpFile), "eval" )
      FileDelete, % tmpFile
      JSON._AddMethods(JS)
      Return JS
   }

   _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.("delete ActiveXObject; delete GetObject;")
      JS.(JScript)
   }

   _CreateObject(ObjJS)  {
      res := ObjJS.IsArray()
      if (res = "")
         Return ObjJS
      
      else if (res = -1)  {
         obj := []
         Loop % ObjJS.length
            obj[A_Index] := this._CreateObject(ObjJS[A_Index - 1])
      }
      else if (res = 0)  {
         obj := {}
         keys := ObjJS.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(ObjJS[k])
      }
      Return obj
   }
}
Bral
Posts: 20
Joined: 04 Apr 2015, 21:24

Re: Need help about Associative Arrays

04 Jan 2018, 22:13

Thanks for teadrinker, your code work fine.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Descolada, hiahkforum, jchestnut, mcd, Sem552, ShatterCoder and 107 guests