Sign in to follow this  
Followers 0
sugi

Check if a var in an array is declared?

12 posts in this topic

I need to pass an array to an udf and need to check if all vars in this array are declared so I can skip those that are not declared.

To check if I have an array is easy with IsArray...

To check if a variable is declared should be possible with IsDeclared. But IsDeclared doesn't accept vars with an array index. Is there a way to check if a variable in an array is declared?

If I have the following code

Dim $a[5]
MsgBox(0, '', $a[0])
Then $a[0] equals 0 but I have no way to check if the 0 was set by my script or by AutoIt when creating the array.

Any ideas?

Share this post


Link to post
Share on other sites



I need to pass an array to an udf and need to check if all vars in this array are declared so I can skip those that are not declared.

To check if I have an array is easy with IsArray...

To check if a variable is declared should be possible with IsDeclared. But IsDeclared doesn't accept vars with an array index. Is there a way to check if a variable in an array is declared?

If I have the following code

Dim $a[5]
MsgBox(0, '', $a[0])
Then $a[0] equals 0 but I have no way to check if the 0 was set by my script or by AutoIt when creating the array.

Any ideas?

<{POST_SNAPBACK}>

not sure i understand your issue. here's a test script that shows that vars can be in arrays:

Dim $A[2]
Dim $test1
$A[0] = "test1"
$A[1] = "test2"
;
testVars()
;
Func testVars()
   For $x = 0 To UBound($A) - 1
      If Not IsDeclared($A[$x]) Then MsgBox(0, 'debug', 'not declared:' & $A[$x])
   Next
EndFunc  ;==>testVars

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

No, that has nothing to do with my problem.

I have an Array declared as $a[5].

Then I set $a[3]=0.

Then the Array gets passed to an UDF which doesn't know which part of the array contains data.

This UDF tries to find the data in the array. <- Currently this step seems to be impossible

It is impossible since $a[0] equals to 0, $a[1] equals to 0, $a[2] equals to 0, $a[3] equals 0, $a[4] equals to 0. I cannot check if this 0 belongs to the data that got passed to my UDF or if it's a leftover from creating the array.

Share this post


Link to post
Share on other sites

The only solution is to create a sentinel to put one past the last element that has been set. Something like "NULL" or another unique string/number that won't appear in your data. Then you can loop until that sentinel is found.

For example:

Dim $a[5]
$a[0] = 0
$a[1] = 352532
$a[2] = "Cool"
$a[3] = "NULL"
; $a[4] hasn't been initialized

For $i = 0 To UBound($a)-1
    If $a[$i] == "NULL" Then ExitLoop; Be sure to do case sensitive
    MsgBox(4096, "$a[" & $i & "]", $a[$i])
Next

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

No, that has nothing to do with my problem.

I have an Array declared as $a[5].

Then I set $a[3]=0.

Then the Array gets passed to an UDF which doesn't know which part of the array contains data.

This UDF tries to find the data in the array. <- Currently this step seems to be impossible

It is impossible since $a[0] equals to 0, $a[1] equals to 0, $a[2] equals to 0, $a[3] equals 0, $a[4] equals to 0. I cannot check if this 0 belongs to the data that got passed to my UDF or if it's a leftover from creating the array.

<{POST_SNAPBACK}>

ok understand now. What about setting your own initial value for all array entries and test for that ?

; init logic
Dim $A[5]
For $x = 0 to 4   
   $A[$x] = "-Null-"
Next
; rest of script logic
$A[0] = 0
$A[1] = "0"
$A[2] = ""
$A[3] = "null"
;$A[4] = 
;
testVars($a)
;
Func testVars($testArray)
   Local $x
   For $x = 0 To UBound($testArray) - 1
      If $testArray[$x] == "-Null-" Then  
         MsgBox(0, 'debug', $x & " is not used")
      Else
         MsgBox(0, 'debug', $x & " is used:" & $testArray[$x])
      EndIf
   Next
EndFunc  ;==>testVars
Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I personally like to populate with nothing, as it doesn't change the isdeclared state, but it is NOT 0

ex:

dim $a[7]
for $i=0 to ubound($a)-1
$a[$i]=""
next

$a[4]=0

for $i=0 to ubound($a)-1
$x=IsDeclared($a[$i])
msgbox(1,$x,$a[$i])
next

and it should take up less memory for large arrays.


AutoIt3, the MACGYVER Pocket Knife for computers.

Share this post


Link to post
Share on other sites

I personally like to populate with nothing, as it doesn't change the isdeclared state, but it is NOT 0

ex:

dim $a[7]
for $i=0 to ubound($a)-1
$a[$i]=""
next

$a[4]=0

for $i=0 to ubound($a)-1
$x=IsDeclared($a[$i])
msgbox(1,$x,$a[$i])
next

and it should take up less memory for large arrays.

<{POST_SNAPBACK}>

Actually, I think the opposite might be true. IIRC, Jon said that the memory for an element in an array isn't allocated until you attempt to assign to it for the first time. Since you are attempting to assign an empty string, you're causing the element to be allocated, so even though its holding nothing, its still holding more than what it was when it had 0 in it. This could have been changed or be inaccurate, however. I vaguely remember Jon saying something like this and that ReDim'ing an array that wasn't full would cause the array to take up more memory capacity since even non-used elements got allocated by ReDim.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

When creating arrays you are limited to up to 64 dimensions and/or a total of 16 million elements. (Technical: The internal table of 4 bytes per element is allocated at the time of creation, but the actual memory for each element is ONLY allocated on that elements first use).

*** Matt @ MPCS

Edited by Matt @ MPCS

Share this post


Link to post
Share on other sites

Sorry, I should have clarified. I think it will take up less memory than placing -Null- in all the slots.

How much memory is taken up by an array of ""?

$array1=StringSplit("Memory Load (Percentage of memory in use),Total physical RAM,Available physical RAM,Total Pagefile,Available Pagefile,Total virtual,Available virtual",",")

Dim $array[10000]
$y=MemGetStats ( )
$x=MemGetStats ( )
for $i=0 to 9999
$array[$i]=""
Next
$x=MemGetStats ( )
For $i=0 To 5
    MsgBox(1,$array1[1+$i],$x[$i]&@CRLF&$y[$i]& @CRLF & "difference " & $y[$i]-$x[$i] )
Next

AutoIt3, the MACGYVER Pocket Knife for computers.

Share this post


Link to post
Share on other sites

"" is 1 byte while "-Null-" is 6.

*** Matt @ MPCS

Share this post


Link to post
Share on other sites

A sentinel is really all that's necessary, not setting every element to something unique.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

I agree with ya, but if you are making a sentinal, you could just store that.

Dim $a[10000]
$sentinal=0

; do a bunch of assigns
$sentinal=12; the last one you did, or $sentinal=$sentinal+1 on each function assignment.

for $i = 0 to $sentinal; instead of the ubound.

Anyway just a theory.

You could use -null- as the sentinal, and keep moving it as well, but that might do a lot of looping to find it each time.

Edited by scriptkitty

AutoIt3, the MACGYVER Pocket Knife for computers.

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