Sign in to follow this  
Followers 0
Alandor

Question about arrays and zero

20 posts in this topic

Hello, I need some help with arrays and the use of zero as a value on them. I would like to know which is the best way to work with as I found pretty annoying to use them on any logical compare operation as it seems to consider an empty string (""), the number zero (0) and a non initialized index exactly the same which is a problem when comparing. How do you work around this issue when working with arrays ?

Thanx very much in advance. :huh2:

Greetings.

Share this post


Link to post
Share on other sites



JohnOne, try it this way:

Local $array[3] = ["a","b",""]

For $i = 0 To 2
    If $array[$i] = 0 Then
        MsgBox(0,"","I'm right")
        Exit
    EndIf
Next

MsgBox(0,"","I'm wrong")

Your way it's doing a case sensitive string comparison against an number which gets converted to the string "0", this way it's doing a string to number comparison and strings evaluate to 0.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

When you use a numeric compare operator, the string gets automatically run through Number(). So if the string was "0" or "123" the operator would work as expected. But a non numeric string like "onetwothree" is an invalid input to Number(), so it returns 0. This is why you get:

If "123" = 123 Then MsgBox(64, "Test", '"123" = 123')
If "OneTwoThree" = 0 Then MsgBox(64, "Test", '"OneTwoThree" = 0')

:huh2:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

VarGetType() can tell whether it is a string or what ever type it is. Then you have the Is*() functions which can tell you if it is a certain type. These functions used as required may help to get type comparison correct. If you want to force type change when comparing then you can use such functions as Number(), Int(), String() etc.

AFAIK, if you let AutoIt handle different type comparison, then AutoIt tries to handle it as best it can, by converting the type if needed to avoid type mismatch error by being compatible. IMO, AutoIt does quite well in many situations. It is recommended in the help file to not mix types in an array but no one seems to comply. :huh2:

Example of testing for type integer and then testing for value of 0.

Local $array[5] = ['a', 'b', '', 0, '0']

For $i = 0 To UBound($array) -1
    ; variable type is integer
    If StringLeft(VarGetType($array[$i]), 3) = 'Int' And $array[$i] = 0 Then
        MsgBox(0, @ScriptName, _
                'VarGetType = ' & VarGetType($array[$i]) & @CRLF & _
                'Index = ' & $i & @CRLF & _
                'Value = ' & $array[$i] _
            )
    EndIf
    ; ... is integer
    If IsInt($array[$i]) And $array[$i] = 0 Then
        MsgBox(0, @ScriptName, _
                'IsInt = ' & (IsInt($array[$i]) = True) & @CRLF & _
                'Index = ' & $i & @CRLF & _
                'Value = ' & $array[$i] _
            )
    EndIf
Next

The Is*() functions that you choose can depend on the types that you want handled.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanx very much for the help. I think the VarGetType() function will do the trick, thanx MHZ. :huh2: I would like to ask just one more question, is it possible to know if an "empty" row on an array hasn't been assigned ? I mean an empty arrow and and arrow assigned to "" will not differentiate so, is there a way to know which case is ??

P.D.: Actually my problem was with a numeric only array (not a mixed one) but with empty "slots" in the middle so when comparing I was getting the number 0 treated the same way the empty slots were. I didn't think on use the "Is" functions, I forgot completely them but I have seen now using "IsNumber" possibly is the best way for this case

P.D.2: MHZ thanx too for pointing the "Is" functions. I didn't think on use them just because I forgot completely. So my fault, I have seen now using "IsNumber" possibly is the best way for this exact case. I am afraid I was really tired when I wrote my last post and my mind was not working correctly. :alien:

Thanx again. ;)

Greetings.

Edited by Alandor

Share this post


Link to post
Share on other sites

If you need to differentiate between unassigned elements and "" in an array, just loop thru your array before actual use, forcing a known value (special string or number, different type) you will never be storing in any element during actual use.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I would like to ask just one more question, is it possible to know if an "empty" row on an array hasn't been assigned ? I mean an empty arrow and and arrow assigned to "" will not differentiate so, is there a way to know which case is ??

Whether you declare a variable or an array, the values will be an empty string. If you assign something other then an empty string, then yes, you may know as it is not an empty string. if you assign $array[$i] = "" then not a hope as nothing has changed value wise.

P.D.: Actually my problem was with a numeric only array (not a mixed one) but with empty "slots" in the middle so when comparing I was getting the number 0 treated the same way the empty slots were.

Technically, it is mixed as Autoit declares as empty string and you choose what is assigned numerical. This is fine as most if not all spreadsheet programs allow this in numerical spreadsheets. For you, as the programmer behind the code, the conditions in handling these different types may need to be like as if they merge well as being one happy event. What looks easy in a program can be complex handling by the programmer.

Edit: Oh forgot, IsNumber() is fine if it suits your needs. :huh2:

Edited by MHz

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Besides using IsNumber(), IsInt() or VarGetType() to test the variable type, another possibility (which I sometimes use) would be to set a specific value (eg empty string value = -1) to act as a flag. I see the the downside to this approach as being unnecessary memory consumption. For that reason I tend to avoid it, but it in certain situations the approach may have practical value.

Edit

(Hmm I think that's what JCHD said earlier) :huh2:

Edited by czardas

Share this post


Link to post
Share on other sites

czardas, yes, actually is a trick I use sometimes too. This time It was a problem as I needed to work with the empty slots directly.

jhcd, you are right, I didn't thought on initialize the array to a non use value when declaring because most of the arrays I was using were large and I don't know how many elements will have in declare time so It didn't came to my mind, but I am afraid I will have to create a very large array and initialize this way sometimes.

MHZ, yeah, actually It is really "funny" how sometimes things that seems complicated at user level can be very simple at programming level and the same time simpler ones can be really complicated.

Thanx very much to all of you for your responses and help. :huh2:

Greetings. ;)

Share this post


Link to post
Share on other sites

What is very large?


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

What is very large?

Well, about one hundred more or less. Not really large, just tend to call large array an array with more than 10 elements. :huh2: Edited by Alandor

Share this post


Link to post
Share on other sites

That's small. Goahead and loop into your array(s) as many times you need to do whatever you need. You won't notice.

100 000 starts being large.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Is it possible to arrange the elements in the array in a way that would avoid the need for data verification? I sometimes use the first element in each row of a 2D array to indicate the number of entries (or Max Index Number) within that particular row. If the declared elements are arranged in order, then I just loop through the valid entries. This method won't work if the values are arranged ad hoc.

Just saw your responce. 100 elements is really small. :huh2:

Share this post


Link to post
Share on other sites

Come on, size does not matter. It is the satisfying conditions that make things happen as expected. :huh2:

Share this post


Link to post
Share on other sites

Yeah but don't expect to reach UBound exactly. Always -1. That's why we all have to loop to try again :huh2:


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Alandor,

Would testing for the length of an array element produce valid results for you?

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Hardly:

Local $a[1]
ConsoleWrite("Uh?  Initial value in array has length " & StringLen($a[0]) & " and an empty string has length " & StringLen("") & @LF)

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I see. Thanx again for the advices. :huh2:

Kylomas, actually I think your idea would work perfectly too in my case, although using IsNumber() easier this time but I will keep the tip for other possible scenarios. Thanx.

Greetings.

Edited by Alandor

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