2. More generally, you simply check if each item you come to is a subarray, and if so go through a for loop on the subarray. This is one of the few algorithms it feels natural to write recursively. This serialize function is something I wrote a while back to quickly print out the contents of most objects. It might give you some ideas.
Code: Select all
msgbox % Serialize( {} ) ;Empty array
msgbox % Serialize( [1,2,3] ) ;Simple array
msgbox % Serialize( {apples:"bananas", grapes:"oranges", pickles:[1,2,3]} ) ;Associative array with a subarray
msgbox % Serialize( new example ) ;Class instance
serialize(obj)
{
if !IsObject(obj)
return ""
str := "{"
for k,v in obj
{
if IsObject(v)
{
if IsFunc(v.name)
v := "Function"
else
v := serialize(v)
}
str .= k ":" v ", "
}
if IsObject(obj.base)
str .= "base:" serialize(obj.base) ", "
return RegexReplace(str, ", $", "") "}"
}
class example
{
__New()
{
this.a := "A"
this.b := "B"
}
}
3. You could write a
custom enumerator. This allows you to continue using for-loop syntax, and preserves the original object.
Code: Select all
;Sample data
arr := { 1:"A", 2:"B", 3:"C", cats:"dogs", zebras:"lions"}
str := "Normal Iteration"
for k,v in arr
str .= "`n" k " = " v
Msgbox %str%
str := "Reverse Iteration"
e := new reverseEnum(arr)
while e[k,v]
str .= "`n" k " = " v
Msgbox %str%
;Enabling arr to use reverseEnum with a for loop
str := "Reverse For Loop"
arr._NewEnum := Func("getReverseEnum")
for k,v in arr
str .= "`n" k " = " v
Msgbox %str%
getReverseEnum(obj)
{
return new reverseEnum(obj)
}
class reverseEnum
{
__New(obj)
{
this.items := {} ;A list of keys and values as the obj currently contains
this.count := 0 ;Count of items found in obj
e := ObjNewEnum(obj) ;Get a normal enumerator
while e[k,v] ;Get all the keys and values and save them for later
if (k != "_NewEnum") ;Filter enum method if it comes up...
this.items[++this.count] := {k:k,v:v}
this.base.__Get := this.Next ;Enables enum[k,v] to call enum.Next(k,v)
}
Next(byref k, byref v)
{
curItem := this.items[this.count] ;Get the current item
k := curItem.k, v := curItem.v ;Set byref variables
return (this.count-- >= 1) ;Decrement count and return whether or not this is the last item
}
}
As a side note, I find this to be misleading:
for each, item in SubArray
It's nice that it reads as an English phrase, but someone not familiar with the syntax may wonder why there is a comma when it isn't appropriate grammatically, and it gives no indication that
each is actually a variable name.