Post by dragonjim on Mar 1, 2012 15:25:35 GMT 1
I'm working on a program with an ever expanding number of records and, rather than create a massive array first off, I decided to use Redim() to steadily increase the size of the array as it was required.
This worked fine for single element arrays - but when I tried it with arrays of more than one element, I got some interesting results as, it turns out, GFA expands the first element rather than the last element first. I'll explain:
The array is a%(2,2) and you fill each element with the value of the first element: e.g. a%(1,1) =1, a%(1,2) = 1, a%(2,1) =2, a%(2,2) =2. If you Redim the array: Redim a%(4,2) for example, the original values of a%(1,1) ... a%(2,2) have been changed as can be seen from this small program below:
OpenW 1
Dim a%(2, 2)
Local m, n
For n = 1 To 2
a%(n, 1) = n : a%(n, 2) = n
Next n
Print "Before Redim:"
For n = 1 To 2 : For m = 1 To 2
Print AT(m * 14, n + 1); "a%("; n; ","; m; ") = "; a%(n, m)
Next m : Next n
ReDim a%(4, 2)
Print : Print "After Redim:"
For n = 1 To 4 : For m = 1 To 2
Print AT(m * 14, n + 5); "a%("; n; ","; m; ") = "; a%(n, m)
Next m : Next n
While MouseK = 0 : Wend
CloseW 1
So what I did instead was create my own little subroutine with an array counter arr_ct% (to alert the program when it is reaching the array limit - I suppose I could have used UBound) for an array arr%(), which appears below as 'Sub Increase_Array(Byref ct)' with accompanying programming to show it works (hopefully!).
OpenW Full 1
Global Dim arr%(10, 10)
Global Dim arr_ct% = 10
Local act% = 0
arr%(1, 1) = 1 : arr%(10, 10) = 10
Print "act%", "UBound(arr%())", "arr%(1,1)", "arr%(10,10)"
Print
Repeat
Increase_Array(act%)
Print act%, UBound(arr%()), arr%(1, 1), arr%(10, 10)
Until act% = 30
While MouseK = 0 : Wend
CloseW 1
Sub Increase_Array(ByRef ct%)
Local n, m
Inc ct%
If ct% > arr_ct%
Dim nw_arr%(arr_ct% + 10, 10)
For n = 1 To 10 : For m = 1 To 10
nw_arr%(n, m) = arr%(n, m)
Next m : Next n
Swap arr%(), nw_arr%()
Add arr_ct%, 10
EndIf
EndSub
Interestingly, although the help file says that Swap can only be used with similar sized arrays, it works perfectly in this situation. (I did trying ReDim-ing arr%() and then re-populating but this was about three times slower and the alternative was quicker to write!)
My questions, as this is the 'Help' section, are:
1. Have I misunderstood ReDim and is there, in fact, a method of using it to get the results I need?
and, if not...
2. Can you suggest any improvements to the above that will make it run quicker? You'll notice I've incremented the array by 10 each time to prevent too much drag on the rest of the program.
This worked fine for single element arrays - but when I tried it with arrays of more than one element, I got some interesting results as, it turns out, GFA expands the first element rather than the last element first. I'll explain:
The array is a%(2,2) and you fill each element with the value of the first element: e.g. a%(1,1) =1, a%(1,2) = 1, a%(2,1) =2, a%(2,2) =2. If you Redim the array: Redim a%(4,2) for example, the original values of a%(1,1) ... a%(2,2) have been changed as can be seen from this small program below:
OpenW 1
Dim a%(2, 2)
Local m, n
For n = 1 To 2
a%(n, 1) = n : a%(n, 2) = n
Next n
Print "Before Redim:"
For n = 1 To 2 : For m = 1 To 2
Print AT(m * 14, n + 1); "a%("; n; ","; m; ") = "; a%(n, m)
Next m : Next n
ReDim a%(4, 2)
Print : Print "After Redim:"
For n = 1 To 4 : For m = 1 To 2
Print AT(m * 14, n + 5); "a%("; n; ","; m; ") = "; a%(n, m)
Next m : Next n
While MouseK = 0 : Wend
CloseW 1
So what I did instead was create my own little subroutine with an array counter arr_ct% (to alert the program when it is reaching the array limit - I suppose I could have used UBound) for an array arr%(), which appears below as 'Sub Increase_Array(Byref ct)' with accompanying programming to show it works (hopefully!).
OpenW Full 1
Global Dim arr%(10, 10)
Global Dim arr_ct% = 10
Local act% = 0
arr%(1, 1) = 1 : arr%(10, 10) = 10
Print "act%", "UBound(arr%())", "arr%(1,1)", "arr%(10,10)"
Repeat
Increase_Array(act%)
Print act%, UBound(arr%()), arr%(1, 1), arr%(10, 10)
Until act% = 30
While MouseK = 0 : Wend
CloseW 1
Sub Increase_Array(ByRef ct%)
Local n, m
Inc ct%
If ct% > arr_ct%
Dim nw_arr%(arr_ct% + 10, 10)
For n = 1 To 10 : For m = 1 To 10
nw_arr%(n, m) = arr%(n, m)
Next m : Next n
Swap arr%(), nw_arr%()
Add arr_ct%, 10
EndIf
EndSub
Interestingly, although the help file says that Swap can only be used with similar sized arrays, it works perfectly in this situation. (I did trying ReDim-ing arr%() and then re-populating but this was about three times slower and the alternative was quicker to write!)
My questions, as this is the 'Help' section, are:
1. Have I misunderstood ReDim and is there, in fact, a method of using it to get the results I need?
and, if not...
2. Can you suggest any improvements to the above that will make it run quicker? You'll notice I've incremented the array by 10 each time to prevent too much drag on the rest of the program.