Does the Array element exist? - WORKAROUND!

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Post Reply
mightycpa
Automation Wizard
Posts: 343
Joined: Mon Jan 12, 2004 4:07 pm
Location: Vienna, VA

Does the Array element exist? - WORKAROUND!

Post by mightycpa » Mon Feb 27, 2017 5:26 am

Hi,

I've got this simple array code:

Code: Select all

ArrayDim>testit,5
Let>testit_0=
Let>testit_1=one
Let>testit_2=two
Let>testit_3=three
Let>testit_5=five

Let>i=0
Repeat>i
   MessageModal>testit_%i%
   Add>i,1
Until>i=6
As you can see, testit_4 does not exist. Is there any way to determine this using code?
Last edited by mightycpa on Tue Feb 28, 2017 6:37 pm, edited 2 times in total.
"A facility for quotation covers the absence of original thought." - Lord Peter Wimsey

User avatar
Marcus Tettmar
Site Admin
Posts: 7380
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Re: Does the Array element exist?

Post by Marcus Tettmar » Mon Feb 27, 2017 8:37 am

It does exist but it's empty. Double click on the TESTIT=<array> in the watch list and you will see testit_4 there with an empty value. You created it when you used ArrayDim. ArrayDim is index 1 based too. Double click on TESTIT=<array> immediately after running the ArrayDim line and you'll see testit_1 thru testit_5. So your testit_0 is not technically part of that array and you'll notice it in the watch list on it's own but not when you drill down in the testit array.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

mightycpa
Automation Wizard
Posts: 343
Joined: Mon Jan 12, 2004 4:07 pm
Location: Vienna, VA

Re: Does the Array element exist?

Post by mightycpa » Mon Feb 27, 2017 1:59 pm

OK, I see what you're saying. Let me rephrase the question. If I change the code to this:

Code: Select all

ArrayDim>testit,5
Let>testit_0=
Let>testit_1=one
Let>testit_2=two
Let>testit_3=three
Let>testit_5=five
Let>testit_6=
Let>testit_10=ten

Let>i=0
Repeat>i
   MessageModal>testit_%i%
   Add>i,1
Until>i=6
In this revised code, testit_ array still contains elements 1 -5. But in addition, variables testit_0, testit_6 and testit_10 have been created. Is there any way to tell using code that these non-array variables exist, given that I know they begin with "testit_" ? Of course, I don't mean by testing if they have a value.
"A facility for quotation covers the absence of original thought." - Lord Peter Wimsey

mightycpa
Automation Wizard
Posts: 343
Joined: Mon Jan 12, 2004 4:07 pm
Location: Vienna, VA

Re: Does the Array element exist?

Post by mightycpa » Tue Feb 28, 2017 6:36 pm

The ASSIGNED command seems to be the workaround for me.

Returns TRUE if the array element has been DIM'd, even if no value assigned.
Returns FALSE if the array element has not been DIM'd and no value assigned.
Returns TRUE if either the array element has been DIM'd, or if a value is assigned to a regular variable

However, ArrayCount> can be tricked into producing false results by creating variables that mimic an array format and surround or invade the array:

Code: Select all

Let>testit_2=two
ArrayDim>testit,4
Let>testit_0=
Let>testit_1=one
//Let>testit_3=three
Let>testit_4=four
Let>testit_5=five
/*
Let>testit_6=
Let>testit_7=
Let>testit_8=
Let>testit_9=
*/
Let>testit_10=ten
ArrayCount>testit,v_cnt1
MessageModal>Array Count is %v_cnt1% (indexes 0,1,2,3,4,5)
Let>testit_7=
ArrayDim>testit,7
ArrayCount>testit,v_cnt2
MessageModal>Now, the Array Count is %v_cnt2% (indexes 0,1,2,3,4,5,6,7)
MessageModal>Step through code, stop here, look array in at Watch List. %CRLF%%CRLF% # of array elements in Watch List = 4

Let>v_myarraycount=0
Let>v_idxs= :indexes
Let>i=0
Repeat>i
   Assigned>testit_%i%,v_YN
   If>v_YN=TRUE
     Add>v_myarraycount,1
     ConCat>v_idxs, %i%,
   Endif
   //MessageModal>testit_%i% - %v_YN%
   Add>i,1
   //MessageModal>MS Array Count is %v_cnt2% and my array count is %v_myarraycount%
Until>i=11

MessageModal>MS Array Count is %v_cnt2% (indexes 0,1,2,3,4,5,6,7) and my array count is %v_myarraycount% %v_idxs%
But if I need to know that I had 7 elements in my array, I don't know how to do that.
"A facility for quotation covers the absence of original thought." - Lord Peter Wimsey

User avatar
Marcus Tettmar
Site Admin
Posts: 7380
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Re: Does the Array element exist? - WORKAROUND!

Post by Marcus Tettmar » Tue Feb 28, 2017 7:54 pm

Yes, use Assigned.

Use ArrayCount to get the number of (proper) elements in the array.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

mightycpa
Automation Wizard
Posts: 343
Joined: Mon Jan 12, 2004 4:07 pm
Location: Vienna, VA

Re: Does the Array element exist? - WORKAROUND!

Post by mightycpa » Tue Feb 28, 2017 8:35 pm

Hi Marcus,

If you step through the code scenarios in this post, then open the array in the watch list, you'll see that ArrayCount returns counts inconsistent with 3 elements seen in the Watch List. In all cases, it overcounts.

1) INVADE THE ARRAY WITH A VARIABLE
Because testit_2 is created before the Array was DIM'd, testit_2 is not shown in the watch list as part of the array, but it is counted as an element in the array

Code: Select all

Let>testit_2=two
ArrayDim>testit,4
ArrayCount>testit,v_cnt1
2)SURROUND THE ARRAY WITH TWO VARIABLES
Non-array variables testit_0 and testit_5 are created. Array Count now returns 6, counting both of them, but only 3 array elements appear in the Watch list

Code: Select all

Let>testit_2=two
ArrayDim>testit,4
ArrayCount>testit,v_cnt1
Let>testit_0=zero
Let>testit_5=five
ArrayCount>testit,v_cnt2
3)ADD A GAP IN THE SEQUENCE
Assign will count the extra variable, if you allow it, but Array Count will not, which is consistent with the help.
Array Count =5
Assign Count = 6
Watch List = 3

Code: Select all

Let>testit_2=two
ArrayDim>testit,4
ArrayCount>testit,v_cnt1
Let>testit_0=zero
//put a gap in the index here
Let>testit_6=five
ArrayCount>testit,v_cnt2
Let>v_AssignCount=0
Let>i=0
Repeat>i
   Assigned>testit_%i%,v_YN
   If>v_YN=TRUE
     Add>v_AssignCount,1
   Endif
   Add>i,1
Until>i=7
4) SORT THE ARRAY AND WATCH IT MIX AND MATCH ELEMENT VALUES
Try this with and without the gap introduced in #3, and you'll get different results

Code: Select all

Let>testit_2=two
ArrayDim>testit,4
Let>testit_1=ultimate
Let>testit_3=first
Let>testit_4=middle
ArrayCount>testit,v_cnt1
Let>testit_0=zero
//no gap in this series
Let>testit_5=five
ArrayCount>testit,v_cnt2
//in the watch list, array values are: ultimate, first, middle :original indexes are 1,3,4
ArraySort>testit
//after the sort, sorted array values are: five, two, ultimate :original indexes are 5,2,1; new indexes are 1,3,4
// do it with the gap in #3, and the sorted values are taken from indexes 5,1,0
So at least for me, dynamically built arrays used to hold data from non-sequential numbered lists are probably the wrong use of an array. Regular variables are the way to go. I admit that the scenarios presented are unlikely, but some unlikely data is how I found this.
"A facility for quotation covers the absence of original thought." - Lord Peter Wimsey

Post Reply
cron
Sign up to our newsletter for free automation tips, tricks & discounts