Associative array question when the data is from the web

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: Associative array question when the data is from the web

29 Jul 2021, 14:54

malcev wrote: why do You prefer to use eval but not json object?
No, I prefer this variant:

Code: Select all

JsonToAHK(json, rec := false) {
   static doc := ComObjCreate("htmlfile")
        , __ := doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
        , JS := doc.parentWindow
   if !rec
      obj := %A_ThisFunc%(JS.JSON.parse(json), true)
   else if !IsObject(json)
      obj := json
   else if JS.Object.prototype.toString.call(json) == "[object Array]" {
      obj := []
      Loop % json.length
         obj.Push( %A_ThisFunc%(json[A_Index - 1], true) )
   }
   else {
      obj := {}
      keys := JS.Object.keys(json)
      Loop % keys.length {
         k := keys[A_Index - 1]
         obj[k] := %A_ThisFunc%(json[k], true)
      }
   }
   Return obj
}
However, if you need to pass a "not strong" Json string, this will not work:

Code: Select all

notStrongJson = {key: "value"}
obj := JsonToAHK(notStrongJson)

JsonToAHK(json, rec := false) {
   static doc := ComObjCreate("htmlfile")
         , __ := doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
         , JS := doc.parentWindow
   if !rec
      obj := %A_ThisFunc%(JS.eval("(" . json . ")"), true)
   else if !IsObject(json)
      obj := json
   else if JS.Object.prototype.toString.call(json) == "[object Array]" {
      obj := []
      Loop % json.length
         obj.Push( %A_ThisFunc%(json[A_Index - 1], true) )
   }
   else {
      obj := {}
      keys := JS.Object.keys(json)
      Loop % keys.length {
         k := keys[A_Index - 1]
         obj[k] := %A_ThisFunc%(json[k], true)
      }
   }
   Return obj
}
But eval still works:

Code: Select all

notStrongJson = {key: "value"}
MsgBox, % JsonToAHK(notStrongJson).key

JsonToAHK(json, rec := false) {
   static doc := ComObjCreate("htmlfile")
         , __ := doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
         , JS := doc.parentWindow
   if !rec
      obj := %A_ThisFunc%(JS.eval("(" . json . ")"), true)
   else if !IsObject(json)
      obj := json
   else if JS.Object.prototype.toString.call(json) == "[object Array]" {
      obj := []
      Loop % json.length
         obj.Push( %A_ThisFunc%(json[A_Index - 1], true) )
   }
   else {
      obj := {}
      keys := JS.Object.keys(json)
      Loop % keys.length {
         k := keys[A_Index - 1]
         obj[k] := %A_ThisFunc%(json[k], true)
      }
   }
   Return obj
}
wetware05
Posts: 750
Joined: 04 Dec 2020, 16:09

Re: Associative array question when the data is from the web

29 Jul 2021, 18:20

Hello.

Another simpler approach is to treat information as a CSV table. I have tried the "ahkstudent" script and you do not reach the "atestfile.txt" file on the hard drive. I have created it and I have tried several options, but the idea begins badly from the beginning, because the matrix is ​​poorly delimited with the commas.

With the CSV.ahk library everything becomes simpler (https://www.autohotkey.com/boards/viewtopic.php?t=34853). It is more intuitive and simple that they have been shared above.

Code: Select all

SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Include CSV.ahk

*F3:: ;Control+F3
FileDelete, ExampleCSVFile_2.csv
Return

*F4::
FileAppend,
(
ItemM,Digital,Both,LocalDel,Check
ItemM-a,Digital-a,Both-a,LocalDel-a,Check-a
ItemM-b,Digital-b,Both-b,LocalDel-b,Check-b
ItemM-c,Digital-c,Both-c,LocalDel-c,Check-c
ItemM-d,Digital-d,Both-d,LocalDel-d,Check-d
), ExampleCSVFile_2.csv
return

*F5::
; load a CSV file using CSV_Load(FileName, CSV_Identifier, Delimiter)
; "data" is the CSV_Identifier we are using to refer to the file we've loaded, you can give it any name you'd like
CSV_Load("ExampleCSVFile_2.csv","data")

; Reading a Cell using CSV_ReadCell(), should show "ItemM-a"
MsgBox % "Contents of Cell in row number 2, and column 1: " CSV_ReadCell("data",2,1)
Return
I have delimited three functions keyboard shortcuts to see it clearer. The second option creates a data matrix of 5 columns and 5 rows (it does with "fileappend", the first is the header, as in every spreadsheet).
magusneo
Posts: 45
Joined: 30 Sep 2013, 06:34

Re: Associative array question when the data is from the web

01 Aug 2021, 06:11

malcev wrote:
29 Jul 2021, 13:02
teadrinker, why do You prefer to use eval but not json object?
magusneo, exactly this script You cannot use because Object.keys method You can use from IE9.
But eval You can use also in earlier versions of IE with this trick:

Code: Select all

str = {"ItemN":625,"Digital":"Both","LocalDel":"Check"}
jsObj := GetJS().("(" . str . ")")
MsgBox, % jsObj.ItemN

GetJS() {
   static doc := ComObjCreate("htmlfile")
         , __ := doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
         , JS := doc.parentWindow
   JS.execScript(" ")   ; Initializing the JavaScript interpreter for IE < IE9
   Return ObjBindMethod(JS, "eval")
}
thanks!
:bravo:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: filipemb, mikeyww and 321 guests