Page 1 of 1

Formatting objects/arrays

Posted: 14 Feb 2024, 21:43
by Hellbent
Hi I'm hoping someone can help me out with a formatting tool I'd like to have.

The purpose of the tool is to swap between a long format and a short format for objects / arrays

Something like this but with the ability to deal with nested objects and arrays as well as simple ones.

.
20240214211902.png
20240214211902.png (9.21 KiB) Viewed 564 times
.

My goal is to be able to paste in the code for an object into an edit control and switch its formatting in another edit control ready to copy and paste.

I'm pretty sure that I could work through any problem that needs to be solved to get this to work but I don't have experience in this sort of thing so I don't know what problems I would even face so I thought I ask here to see if someone has some code already or knows what to do to get this outcome off the top of their head.

Anyways, thanks in advance and here is the basic design for the ui.

Code: Select all

#SingleInstance Force

Gui, New, +AlwaysOnTop 
Gui, Margin, 10 , 10
Gui, Add, Text, xm ym w700 r3 Border Center 0x200 , Input
Gui, Add, Edit, xm y+m wp r7 -Wrap WantTab
Gui, Add, Text, xm y+m w700 r3 Border Center 0x200 , Output
Gui, Add, Radio, xm y+m w60 section checked Group vRadioGroup , Output 1
Gui, Add, Radio, xm y+m wp , Output 2
;~ Gui, Add, Radio, xm y+m wp , Output 3
Gui, Show, Hide
Gui, -Caption +LastFound
SetTitleMatchMode, 2 
WinGetPos,,, w , h 
Gui, Add, Edit, %  "ys w" w - 60 - 30 " r7 -Wrap wanttab"
Gui, +Caption
Gui, Show, AutoSize
return

GuiClose:
GuiContextMenu:
*ESC::ExitApp






Re: Formatting objects/arrays

Posted: 14 Feb 2024, 23:18
by mikeyww
If the comma is a separator, you can use StrSplit to get the parts. If colon is a secondary separator, you can use StrSplit to get the secondary parts. You can then reassemble them in one or two loops.

Alternatively, you could append the code to your script, run the code, and then use the array itself, but this approach seems more complicated.

Re: Formatting objects/arrays

Posted: 15 Feb 2024, 00:57
by Hellbent
mikeyww wrote:
14 Feb 2024, 23:18
Alternatively, you could append the code to your script, run the code, and then use the array itself, but this approach seems more complicated.
That might actually be the simplest way (haven't really thought it through yet).
One of the issues I could see with doing my splits would have been things like quotes, commas between quotes, etc.
I think I would basically would have needed to create recursive function that goes up a branch as far as it can go and then works back out from there (I'm not certain though).

I think that with your idea of appending it to the script I can just write a few nested for loops.
Thanks for the idea I'll give it some more thought.

Re: Formatting objects/arrays

Posted: 15 Feb 2024, 07:39
by mikeyww

Code: Select all

#Requires AutoHotkey v1.1.33
str1 := "obj := {x: ""a, b"", ""C"": 3}"
MsgBox 64, Result, % str2 := parseObjString(str1)

parseObjString(str) {
 Static script  := "script2.ahk"
      , out     := "out.txt"
 objName := Trim(StrSplit(str, ":=")[1])
 FileRecycle % script
 FileAppend,
 (
 #Requires AutoHotkey v1.1.33
 %str%
 txt := ""
 For k, v in obj
  txt .= (txt = "" ? "" : "``n") "%objName%." k " := " v
 FileRecycle %out%
 FileAppend `% txt, %out%
 ), % script
 RunWait % script
 FileRead str2, % out
 FileRecycle % script
 FileRecycle % out
 Return str2
}
image240215-0747-001.png
Output
image240215-0747-001.png (14.88 KiB) Viewed 513 times

Re: Formatting objects/arrays

Posted: 15 Feb 2024, 14:09
by Hellbent
Thanks @mikeyww.
I have expanded out the logic a bit more but it still has some ways to go.
One issue of many is that I need a better solution for is how to determine if a key value is an array.

Code: Select all

#Requires AutoHotkey v1.1.33
;str1 := "obj := {x: ""a, b"", ""C"": 3}"
str1 = myObj := { RectObj: { X: 10 , Y: 10 , W: 100 , H: 100 } , Radius: 30 , FontObj: { Type: """Segoe UI""" , Size: 10 , Color: """0xFFFFFFFF""" } , OtherKey: """Other Value""" , TestArray: [ 1 , 2 , 3 ] } 
str2 =
(
	Main := {}
 	Main.Categories := {}
	Main.Categories.Headers := [ "PopUpWindow" ]
	Main.Categories.Icons := [ "" ]

	Main.Categories.PopUpWindow := {}
	Main.Categories.PopUpWindow.Headers := [ "New" ]
	Main.Categories.PopUpWindow.Icons := [ "" ]

	Main.Categories.PopUpWindow.New := {}
	Main.Categories.PopUpWindow.New.Steps := []
	Main.Categories.PopUpWindow.New.OutputString := "Test String"

	Main.Categories.PopUpWindow.New.Steps[ 1 ] := {}
	Main.Categories.PopUpWindow.New.Steps[ 1 ].StepHeader := "AutoShow"
	Main.Categories.PopUpWindow.New.Steps[ 1 ].Headers := []
	Main.Categories.PopUpWindow.New.Steps[ 1 ].Icons := []
	Main.Categories.PopUpWindow.New.Steps[ 1 ].Values := []
	Main.Categories.PopUpWindow.New.Steps[ 1 ].Type	:= "Custom"
)

MsgBox 64, Result, % str2 := parseObjString(str1)

parseObjString(str) {
 Static script  := "script2.ahk"
      , out     := "out.txt"
 objName := Trim(StrSplit(str, ":=")[1])
 FileRecycle % script
 FileAppend,
 (
 #Requires AutoHotkey v1.1.33
 %str%
 txt := ""
 	;For k, v in obj
 	For k, v in %objName%	{
  		if( isObject( %objName%[ k ] ) ){
			txt .= (txt = "" ? "" : "``n")
			if( inStr( k , " " ) ){
				isArray := 0
				txt .= "%objName%[ """ k """ ] := {}"
			}else{
				if( %objName%[ k ].Length() >= 1 ){
					isArray := 1
					txt .= "%objName%." k " := []" 
				}else{
					isArray := 0
					txt .= "%objName%." k " := {}"
				}
			}
			for j , i in %objName%[ k ]	{
				txt .= (txt = "" ? "" : "``n") 
				if( inStr( k , " " ) ){
					if( isArray || inStr( j , " " ) ){
						if( isArray )
							txt .= "%objName%[ """ k """ ][ " j " ] := " i
						else 
							txt .= "%objName%[ """ k """ ][ """ j """ ] := " i
					}else
						txt .= "%objName%[ """ k """ ]." j " := " i

				}else{
					if( isArray || inStr( j , " " ) )
						if( isArray )
							txt .= "%objName%." k "[ " j " ] := " i
						else 
							txt .= "%objName%." k "[ """ j """ ] := " i
					else
						txt .= "%objName%." k "." j " := " i
				}

			}
		}else{
			if( inStr( k , " " ) )
				txt .= (txt = "" ? "" : "``n") "%objName%[ """ k """ ] := " v
			else
				txt .= (txt = "" ? "" : "``n") "%objName%." k " := " v
		}
	}
 FileRecycle %out%
 FileAppend `% txt, %out%
 ), % script
 RunWait % script
 FileRead str2, % out
 FileRecycle % script
 FileRecycle % out
 Return str2
}


Re: Formatting objects/arrays

Posted: 15 Feb 2024, 14:12
by mikeyww
I did not look carefully, but you seem to be on the right track. A recursive function may help, but depends on how far you want to go with this. Best of luck!

Re: Formatting objects/arrays

Posted: 15 Feb 2024, 21:25
by Chunjee
https://biga-ahk.github.io/biga.ahk/#/?id=isarray works like this:

Code: Select all

isArray(param) {

	if (param.getCapacity()) {
		return true
	}
	return false
}

hope this helps

Re: Formatting objects/arrays

Posted: 16 Feb 2024, 17:17
by Hellbent
Chunjee wrote:
15 Feb 2024, 21:25
https://biga-ahk.github.io/biga.ahk/#/?id=isarray works like this:

Code: Select all

isArray(param) {

	if (param.getCapacity()) {
		return true
	}
	return false
}

hope this helps
Thank you for that but it's not quite what I'm looking for, or at least I don't think it is.
What I'm looking to do is distinguish the difference between the two keys in this example.

Code: Select all

obj := {}
obj.Key1 := []
obj.Key2 := {}


The purpose is to be able to swap between it being written like that and being written like this.

Code: Select all

obj := { Key1: [] , Key2: {} }
and the reverse too.

After some thought I don't think that I can actually even do what I need with the current method because of the need to use variables from time to time. It looks like I can only do this by splitting the string.

Re: Formatting objects/arrays

Posted: 26 Feb 2024, 09:00
by Chunjee
it appears to me like a lot of the json libraries also have issues with detecting [] vs {}
They usually resort to counting the indexes, if they start at one and are consecutive, a regular array can be assumed with some accuracy.

Code: Select all

; 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 param_value {
		is_array := i == A_Index
	}
	until (!is_array)
}

Re: Formatting objects/arrays

Posted: 26 Feb 2024, 16:09
by teadrinker
In AHK v1, there is no difference between [] and {}.

Code: Select all

#Requires AutoHotkey v1

obj1 := []
obj1.a := 1
obj1.b := 2

obj2 := {}
obj2.push("a")
obj2.push("b")

for k, v in obj1 {
    MsgBox % k . ": " . v
}

for k, v in obj2 {
    MsgBox % k . ": " . v
}

Re: Formatting objects/arrays

Posted: 09 Mar 2024, 12:15
by Hellbent
teadrinker wrote:
26 Feb 2024, 16:09
In AHK v1, there is no difference between [] and {}.

Code: Select all

#Requires AutoHotkey v1

obj1 := []
obj1.a := 1
obj1.b := 2

obj2 := {}
obj2.push("a")
obj2.push("b")

for k, v in obj1 {
    MsgBox % k . ": " . v
}

for k, v in obj2 {
    MsgBox % k . ": " . v
}
Thank you.
I was playing around after my last post and I found that I couldn't find a meaningful difference between the two besides when it came to using .Length()

I wasn't sure if I was missing something and was going to ask but now there is no need. Thanks again.

I have played around with some ideas and I think that the only thing that I can do here is split the string.
I don't have the patients to work through the problem right now but perhaps in the future I'll put some time into creating this tool.
Really, I should have put Request in the title as I was really just hoping that someone already had code that did something like what I was looking for that I could then add an interface to but for whatever reason I forgot or didn't think about doing it that way (as a request).

For now I'm just going to leave this open and perhaps I'll come back to it another day.