Sign in to follow this  
Followers 0
Jason_A

Insight on how _ArrayAdd works?

5 posts in this topic

Hi, I am working on a script that takes input in the form of numbers and number ranges seperated by commas, and first converts them to an array containing the all the numbers.

I am using StringInStr to look for the dash (to find a range), then using a counter to step through the items and using _ArrayAdd to put them into the working array.

From the way the doc reads, _ArrayAdd should put it at the end of the array, but that does not seem to happen that way.

Func ParseInput()
; First, let's get the data out of the control so we can play with it.
    $unparsed = GuiCtrlRead($Input)
; Break apart the input into array elements based on the commas between them.
    $parsArray = StringSplit($unparsed,",")
; The 0th element created by StringSplit is number of strings returned.
; We don't care about this number and it just gets in the way later
    _ArrayDelete($parsArray,0)
; For the next part, we'll go through each of the elements in our new array
    For $i = 0 to UBound($parsArray)
        MsgBox(0,"step1","Value= " & $parsArray[$i])
    ; Check to see if the element contains a dash which means it is a range.
        If StringInStr($parsArray[$i],"-") > 0 Then
        ; If it is a range, split the two ends into separate elements.  
            $strArray = StringSplit($parsArray[$i],"-")
        ; Let's step between the low element and the high element.
            For $j = Number($strArray[1]) to Number($strArray[2])
            ; Add each element on to the end of our original array.
                _ArrayAdd($parsArray,$j)
            Next
        ; This range is done, so the element that described it is unnessary (and dangerous.)
            _ArrayDelete($parsArray,$i)
        EndIf
; If the element doesn't contain a dash, convert it from a string to a number.
; This line commented out while debugging other problem.
; $parsArray[$i] = Number($parsArray[$i]) 
    Next
; If we've done everything right, the $parsArray should only contain numbers.
    _ArraySort($parsArray)
    _ArrayDisplay($parsArray, "Right?")
EndFunc

I put that MsgBox in to see how it was seeing the elements. Given input of "5,6-10,12-15" the message box showed 5 then 6-10 then 6 then 7, and the ending array looks like this:

[0] = 5
[1] = 6
[2] = 7
[3] = 8
[4] = 9
[5] = 10
[6] = 12-15

Okay, so it looks like _ArrayAdd is adding the elements directly above the current elements, and I'm guessing UBound($parsArray) equals 3 forever, it's not getting a chance to look at any ranges above the first one.

I suppose I could use _ArrayInsert and pick some exorbitantly high element number, then sort when I'm done. Or I could dimension the array with a large number of elements, and use that large number in the place of UBound($parsArray). Are there any better ways of getting it to put the inserted items at the actual end of the array?

Thanks, Jason.

Share this post


Link to post
Share on other sites



IIRC it redims arrays.

You are correct, it does ReDim. Okay, I give up, how does that help me solve the problem?

Thanks,

Jason

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi, I am working on a script that takes input in the form of numbers and number ranges seperated by commas, and first converts them to an array containing the all the numbers.

I am using StringInStr to look for the dash (to find a range), then using a counter to step through the items and using _ArrayAdd to put them into the working array.

From the way the doc reads, _ArrayAdd should put it at the end of the array, but that does not seem to happen that way.

Func ParseInput()
; First, let's get the data out of the control so we can play with it.
    $unparsed = GuiCtrlRead($Input)
; Break apart the input into array elements based on the commas between them.
    $parsArray = StringSplit($unparsed,",")
; The 0th element created by StringSplit is number of strings returned.
; We don't care about this number and it just gets in the way later
    _ArrayDelete($parsArray,0)
; For the next part, we'll go through each of the elements in our new array
    For $i = 0 to UBound($parsArray)
        MsgBox(0,"step1","Value= " & $parsArray[$i])
    ; Check to see if the element contains a dash which means it is a range.
        If StringInStr($parsArray[$i],"-") > 0 Then
        ; If it is a range, split the two ends into separate elements.    
            $strArray = StringSplit($parsArray[$i],"-")
        ; Let's step between the low element and the high element.
            For $j = Number($strArray[1]) to Number($strArray[2])
            ; Add each element on to the end of our original array.
                _ArrayAdd($parsArray,$j)
            Next
        ; This range is done, so the element that described it is unnessary (and dangerous.)
            _ArrayDelete($parsArray,$i)
        EndIf
; If the element doesn't contain a dash, convert it from a string to a number.
; This line commented out while debugging other problem.
; $parsArray[$i] = Number($parsArray[$i]) 
    Next
; If we've done everything right, the $parsArray should only contain numbers.
    _ArraySort($parsArray)
    _ArrayDisplay($parsArray, "Right?")
EndFunc

I put that MsgBox in to see how it was seeing the elements.  Given input of "5,6-10,12-15" the message box showed 5 then 6-10 then 6 then 7, and the ending array looks like this:

[0] = 5
[1] = 6
[2] = 7
[3] = 8
[4] = 9
[5] = 10
[6] = 12-15

Okay, so it looks like  _ArrayAdd is adding the elements directly above the current elements, and I'm guessing UBound($parsArray) equals 3 forever, it's not getting a chance to look at any ranges above the first one.

I suppose I could use _ArrayInsert and pick some exorbitantly high element number, then sort when I'm done.  Or I could dimension the array with a large number of elements, and use that large number in the place of UBound($parsArray).  Are there any better ways of getting it to put the inserted items at the actual end of the array?

Thanks, Jason.

<{POST_SNAPBACK}>

i didn't have the gui that you're using, so i just worked off of a textbox to get the value, but you should be able to see the array handling in my code anyway... this algo works...

#include <Array.au3>
$unparsed = InputBox("numbers","numbers","5,6-10,12-15")
$parsArray = StringSplit($unparsed,",")
;msgbox(0,"blah",$parsarray[0])
$ub = UBound($parsarray)
for $i = 1 to $ub
_ArrayDisplay($parsarray,"Array")
if StringInStr($parsarray[$i],"-") then
        $start = number(stringleft($parsarray[$i],stringinstr($parsarray[$i],"-")-1))
        $end = number(stringright($parsarray[$i],StringLen($PARSARRAY[$I]) - (stringLEN($START)+1)))
        _ArrayDelete($parsarray,$i)
        $i = $i - 1
        FOR $I2 = $start to $end
        _ArrayAdd($parsarray,$i2)
        $ub = $ub + 1
    Next
    EndIf
    
Next
_ArrayDelete($parsarray,0)
_ArrayDisplay($parsarray,"Array")

it seems to me that the issue is happening because when the for loop is started with the ubound() as the ending qualifier, the ending qualifier doesn't change, even when the value changes... basically even though there are 10 elements, it's only looking through index 3. to combat that, i just decremented the iterator whenever i removed an element, so it would go through all of the original values.

Edited by cameronsdad

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

I just decremented the iterator whenever i removed an element, so it would go through all of the original values.

<{POST_SNAPBACK}>

Thanks, CD!

I came to the same conclusion independently. The original script, with the line

"$i = $i - 1"

added after the _ArrayDelete, works a lot better.

Thanks again,

Jason

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0