Originally just one function, now a library of 4!
Functions included:
Array_Print(Array)
- Returns a textual representation of an array
- Won't print circular arrays (returns error)
Array_Gui(Array)
- Creates a GUI with a treeview representation of an array
- Remembers and goes back to the default GUI
- Resizeable (Can I get a spell check in here?)
- Won't print circular arrays (returns error)
Array_IsCircle(Array)
- Returns a boolean value according to whether or not the array contains itself
Array_DeepClone(Array)
- Returns a copy of the input array, with all sub arrays cloned as well
- Will create a circular reference where there was one in the input array
Example:
Spoiler
Array := {"A":{"Fruit":["Apple", "Apricot"], "Animals":["Aardvark", "Antelope"]}, "B":{"Fruit":["Banana", "Blueberry"], "Animals":["Bee", "Barnacle"]}, "C":"The alphabet :D"} Gui, Add, Text,, % Array_Print(Array) Array_Gui(Array) Gui, Show return GuiClose: Gui, Destroy MsgBox, ( I can detect circular arrays! Array1 := [] Array1[1] := 1 Array2 := [] Array2[1] := Array2 MsgBox, `% "Array1: " Array_IsCircle(Array1) "``n" . "Array2: " Array_IsCircle(Array2) ) Array1 := [] Array1[1] := 1 Array2 := [] Array2[1] := Array2 MsgBox, % "Array1: " Array_IsCircle(Array1) "`n" . "Array2: " Array_IsCircle(Array2) MsgBox, Now that we have a circular array, let's try out our display functions with it! MsgBox, % "Array_Gui: " Array_Gui(Array2) "`nArray_Print: " Array_Print(Array2) MsgBox, ( If I have an array, and I want to make another array with the same contents, I would do this: Array := ["Contents"] Array2 := Array.Clone() Array2[1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) ) Array := ["Contents"] Array2 := Array.Clone() Array2[1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) MsgBox, ( It appears to work just fine. However, if Array has Sub-Array(s): Array := [["Contents"]] Array2 := Array.Clone() Array2[1,1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) ) Array := [["Contents"]] Array2 := Array.Clone() Array2[1,1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) MsgBox, ( The sub-arrays are still linked. To fix this, we need to make a deep clone: Array := [["Contents"]] Array2 := Array_DeepClone(Array) Array2[1,1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) ) Array := [["Contents"]] Array2 := Array_DeepClone(Array) Array2[1,1] := "Different contents" Array_Gui(Array) Array_Gui(Array2) MsgBox, ( All is well at last. One of my favorite features of my deep clone function, is that circular refrences are cloned as well. An array that has a circle like this: A -> B -> C -> B -> C -> ... would be made into an array with a circle like this: X -> Y -> Z -> Y -> Z -> ... To demonstrate this, we can use this code: A := [[[]]] A[1,1,1] := A[1] MsgBox, `% "" . &A[1] " - B's Pointer``n" . &A[1,1,1] " - Pointer to C's contents" X := Array_DeepClone(A) MsgBox, `% "" . &X[1] " - Y's Pointer``n" . &X[1,1,1] " - Pointer to Z's contents" ) A := [[[]]] A[1,1,1] := A[1] MsgBox, % "" . &A[1] " - B's Pointer`n" . &A[1,1,1] " - Pointer to C's contents" X := Array_DeepClone(A) MsgBox, % "" . &X[1] " - Y's Pointer`n" . &X[1,1,1] " - Pointer to Z's contents" return
Code:
Spoiler
; ; Function: ; Array_Print ; Description: ; Quick and dirty text visualization of an array ; Syntax: ; Arrary_Print(Array) ; Parameters: ; Param1 - Array ; An array, associative array, or object. ; Return Value: ; A text visualization of the input array ; Remarks: ; Supports sub-arrays ; Related: ; Array_Gui, Array_DeepClone, Array_IsCircle ; Example: ; MsgBox, % Array_Print({"A":["Aardvark", "Antelope"], "B":"Bananas"}) ; Array_Print(Array) { if Array_IsCircle(Array) return "Error: Circular refrence" For Key, Value in Array { If Key is not Number Output .= """" . Key . """:" Else Output .= Key . ":" If (IsObject(Value)) Output .= "[" . Array_Print(Value) . "]" Else If Value is not number Output .= """" . Value . """" Else Output .= Value Output .= ", " } StringTrimRight, OutPut, OutPut, 2 Return OutPut } ; ; Function: ; Array_Gui ; Description: ; Displays an array as a treeview in a GUI ; Syntax: ; Array_Gui(Array) ; Parameters: ; Param1 - Array ; An array, associative array, or object. ; Return Value: ; Null ; Remarks: ; Resizeable ; Related: ; Array_Print, Array_DeepClone, Array_IsCircle ; Example: ; Array_Gui({"GeekDude":["Smart", "Charming", "Interesting"], "tidbit":"Weird"}) ; Array_Gui(Array, Parent="") { static global GuiArrayTree, GuiArrayTreeX, GuiArrayTreeY if Array_IsCircle(Array) { MsgBox, 16, GuiArray, Error: Circular refrence return "Error: Circular refrence" } if !Parent { Gui, +HwndDefault Gui, GuiArray:New, +HwndGuiArray +LabelGuiArray +Resize Gui, Add, TreeView, vGuiArrayTree Parent := "P1" %Parent% := TV_Add("Array", 0, "+Expand") Array_Gui(Array, Parent) GuiControlGet, GuiArrayTree, Pos Gui, Show,, GuiArray Gui, %Default%:Default WinWaitActive, ahk_id%GuiArray% WinWaitClose, ahk_id%GuiArray% return } For Key, Value in Array { %Parent%C%A_Index% := TV_Add(Key, %Parent%) KeyParent := Parent "C" A_Index if (IsObject(Value)) Array_Gui(Value, KeyParent) else %KeyParent%C1 := TV_Add(Value, %KeyParent%) } return GuiArrayClose: Gui, Destroy return GuiArraySize: if !(A_GuiWidth || A_GuiHeight) ; Minimized return GuiControl, Move, GuiArrayTree, % "w" A_GuiWidth - (GuiArrayTreeX * 2) " h" A_GuiHeight - (GuiArrayTreeY * 2) return } ; ; Function: ; Array_DeepClone ; Description: ; Deep clone ; Syntax: ; Arrary_DeepClone(Array) ; Parameters: ; Param1 - Array ; An array, associative array, or object. ; Return Value: ; A copy of the array, that is not linked to the original ; Remarks: ; Supports sub-arrays, and circular refrences ; Related: ; Array_Gui, Array_Print, Array_IsCircle ; Example: ; Array1 := {"A":["Aardvark", "Antelope"], "B":"Bananas"} ; Array2 := Array_DeepClone(Array1) ; Array_DeepClone(Array, Objs=0) { if !Objs Objs := {} Obj := Array.Clone() Objs[&Array] := Obj ; Save this new array For Key, Val in Obj if (IsObject(Val)) ; If it is a subarray Obj[Key] := Objs[&Val] ; If we already know of a refrence to this array ? Objs[&Val] ; Then point it to the new array : Array_DeepClone(Val,Objs) ; Otherwise, clone this sub-array return Obj } ; ; Function: ; Array_IsCircle ; Description: ; Checks for circular refrences that could crash my other functions ; Syntax: ; Arrary_IsCircle(Array) ; Parameters: ; Param1 - Array ; An array, associative array, or object. ; Return Value: ; Boolean value according to whether it has a circular refrence ; Remarks: ; Takes an average of 0.023 seconds ; Related: ; Array_Gui, Array_Print(), Array_DeepClone() ; Example: ; Array1 := {"A":["Aardvark", "Antelope"], "B":"Bananas"} ; Array2 := Array_Copy(Array1) ; Array_IsCircle(Obj, Objs=0) { if !Objs Objs := {} For Key, Val in Obj if (IsObject(Val)&&(Objs[&Val]||Array_IsCircle(Val,(Objs,Objs[&Val]:=1)))) return 1 return 0 }