Jump to content


Photo

Size Of An Array


  • Please log in to reply
14 replies to this topic

#1 Wireless

Wireless

    GMC Member

  • GMC Member
  • 164 posts
  • Version:GM:Studio

Posted 17 December 2009 - 01:15 PM

As the title says, this is a simple script for checking size of an array or a 2 dimensional array.

Update:
For some strange reason, the array2_get script worked for both 1D and 2D arrays if argument1 was empty. So I did that instead, since it worked out better and the script got shorter.
It will now return -1 whether the array exists or not.

Script: sizeof(string arrayname, int index)
New! v1.1
/************* sizeof() *************\
Check one and two dimensional arrays
									
argument0   = array name			
argument1   = 2D array index		
									
Note: If 1D array, leave arg1 empty 
\************************************/
__check = -1;
if (variable_local_array2_get(argument0,argument1,__check+1))
{
	__check=0;
	while (variable_local_array2_get(argument0,argument1,__check))
	{
		__check += 1;
	}
}
return __check;

Old! v1.0
var __check;
__check = 0;
argument1=-1;
if (argument1<0) //If argument1 is less than 0, check 1 dim array
{
   while (variable_local_array_get(argument0,__check))
   {
	   __check += 1;
   }
}
else //Check 2 dim array
{
   while (variable_local_array2_get(argument0,argument1,__check))
   {
	  __check += 1;
   }
}
return __check;

How to use:
If you want to check a single dimensional array, just leave the second argument empty.
my_array[0]=1;
my_array[1]=1;
my_array[2]=1;
sizeof("my_array"); //Returns 3

If you want to check a 2 dimensional array, you have to put the first index of the array in the second argument.
my_array[0,0]=1;
my_array[0,1]=1;
my_array[0,2]=1;
sizeof("my_array",0); //Returns 3


I've search the forum and couldn't find anything like this that found the size of gm arrays, so I hope this can be of some use. :)

Edited by Wireless, 17 December 2009 - 07:50 PM.

  • 1

#2 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 17 December 2009 - 01:22 PM

Well made script.

Can you give a practical example of use (I use sizeof all the time in C++ but can't see an application in GM)?

Edit: What happens if a value in the array is 0?

Edited by PlasticineGuy, 17 December 2009 - 01:27 PM.

  • 0

#3 ramses12

ramses12

    6

  • GMC Member
  • 5769 posts
  • Version:GM8.1

Posted 17 December 2009 - 01:34 PM

It is practical; for example if you want to check for the largest value in an array, you have to loop sizeof(array_index) times through it; let me write a code here:
/array_min() script;
//argument0 is the array index passed as string
var r,a;
a=argument0;
r=variable_local_array_get(a,0);
for(i=0;i<=sizeof(a);i+=1)if(r>variable_local_array_get(a,i))r=variable_local_array_get(a,i);
return r;

  • 0

#4 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 17 December 2009 - 01:36 PM

Still wondering what happens if a value in the array is 0.
  • 0

#5 ramses12

ramses12

    6

  • GMC Member
  • 5769 posts
  • Version:GM8.1

Posted 17 December 2009 - 02:22 PM

I guess it returns the index of that slot. Unfortunately this is unavoidable unless you make a multi-slot checking for next let's say 20 values to see if it really is the end of the array.
  • 0

#6 Wireless

Wireless

    GMC Member

  • GMC Member
  • 164 posts
  • Version:GM:Studio

Posted 17 December 2009 - 07:56 PM

Thanks for all the nice feedback :)

Still wondering what happens if a value in the array is 0.

I don't really know what you mean? Should it return something else when array[0]=0?
Or do you mean when the array don't exists? I've updated the script so it returns -1 if not.


Edit: And yeah.. First post is now updated.
  • 0

#7 Docopoper

Docopoper

    You are observant!

  • GMC Member
  • 1287 posts
  • Version:GM:Studio

Posted 17 December 2009 - 08:06 PM

The alternative to this is using: ds_list & ds_grid functions. like it though.
  • 0

#8 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 17 December 2009 - 11:27 PM

I mean because if the element in the array is 0, it will stop the while loop (0 is false).
  • 0

#9 Shadow Link

Shadow Link

    GMC Member

  • GMC Member
  • 1578 posts

Posted 18 December 2009 - 12:06 AM

What PlasticineGuy is asking is what if it detected "array[0] = 0".

The if statement:
if(0) // <--- False
{
	//This will not happen
}

There is also another problem.
array[0] = 1
array[1] = 1
array[2] = 1
array[5] = 1
array[7] = 1
array[113] = 1
array[157] = 1

Your script will return 3, but what about all 7?
  • 0

#10 PlasticineGuy

PlasticineGuy

    GMC Member

  • New Member
  • 2384 posts

Posted 18 December 2009 - 12:14 AM

Exactly. GM pre-initialises all unused indices to 0; e.g.
array[<some big number < 32000>] = 0;
is equivalent to:
var i;
for(i = 0; i <= <some big number < 32000>; i += 1) {
	 array[i] = 0;
}

  • 0

#11 Wireless

Wireless

    GMC Member

  • GMC Member
  • 164 posts
  • Version:GM:Studio

Posted 18 December 2009 - 08:09 AM

Exactly. GM pre-initialises all unused indices to 0; e.g.

array[<some big number < 32000>] = 0;
is equivalent to:
var i;
   for(i = 0; i <= <some big number < 32000>; i += 1) {
		array[i] = 0;
   }

I've checked little around the function "variable_local_array_get()".. It is ridiculous how that function works, and I see what you mean now.. I thought it checked for initialized array, not if the value was 0 or not..

Well then, this script is pretty much useless, just as the "variable_local_array_get()" is..
  • 0

#12 ramses12

ramses12

    6

  • GMC Member
  • 5769 posts
  • Version:GM8.1

Posted 18 December 2009 - 02:53 PM

There is a solution that works perfectly, but it would be EXTEMELY slow. The alternative is:
var i,e,a;
i=0;
e=0;
a=argument0;
while(i<32000){
if(variable_local_array_get(a,i)==0)e+=1;
else e=0;
i+=1;
};
return 32000-e;
Changing 32000 to a smaller number should improve performance but limit the script capability (I hope you understand why).

Edit: It's pretty hard to believe that someone would use a 32.000 slots array. Just mention that the user can change that number to the maximum possible used slot. For example a number of 500 imporoves the performance highly.

PS: Don't blame variable_local_array_get(), it's only a poor function :)

Edited by ramses12, 18 December 2009 - 03:00 PM.

  • 0

#13 rf Larke

rf Larke

    GMC Member

  • New Member
  • 70 posts

Posted 30 June 2010 - 04:31 AM

Just wondering if someone can help shed some light on a problem I'm having.

I have a little message box script that relies on arrays to store the text. When you press X, it figures out which index we're on currently (via arraysize), increases the value, and displays it. If there is no larger index, then we go to a default end message.

But, for some reason I cannot figure out, I keep getting this error message when running:

"ERROR in
action number 1
of Step Event
for object ctscn:

In script arraysize:
Error in code at line 10:
if (variable_local_array2_get(argument0,argument1,
^
at position 6: Expression expected
"

create:
arraypos=0
msg[0]="Hello!"
msg[1]="How do you fare?"
msg[2]="I hope you are well."
displayed=msg[0]

step:
if keyboard_check_pressed(ord("X"))
  {
  if arraypos<arraysize("msg")
    {  
    arraypos+=1
    displayed=execute_string("return msg["+string(arraypos)+"]") 
    }   
  else 
    displayed="End of line"
  }

  • 0

#14 rf Larke

rf Larke

    GMC Member

  • New Member
  • 70 posts

Posted 01 July 2010 - 12:04 AM

BUMP: Ah, seems that it freaks out if the array index's value is a string. it works fine if it's an integer.

Can anyone help me?
  • 0

#15 torigara

torigara

    GMC Member

  • GMC Member
  • 6483 posts

Posted 01 July 2010 - 06:11 AM

As pointed out above, the script only finds the first array element that is equal to (or smaller than) 0. Naturally, all of elements must be numbers.

It is advised to use other mean to actually count the size of array. Either use a data structure instead, or keep track of the size on your own: E.g.:
msg[0]="Hello!"
msg[1]="How do you fare?"
msg[2]="I hope you are well."
msg_size = 3; // This is the size of the array

If you want to keep using the script knowing its limitation, you could make it work with strings like the following.
if (!variable_local_exists(argument0)) return -1; // The array does not exist.

var size, value;
for (size = 0; size < 32000; size += 1) {
	value = variable_local_array2_get(argument0, argument1, size);
	if (is_real(value)) { // We have to split it into two ifs or we get an error when the value is a string.
		if (value == 0) {
			// If we got 0, either the place is out of bounds or it actually has a value 0.
			// There is no practical way to tell one from another, but we assume it the end of array.
			break;
		}
	}
}
return size;
By the way, instead of using execute_string("return msg["+string(arraypos)+"]") you can directly write msg[arraypos].

Edited by torigara, 01 July 2010 - 09:19 AM.

  • 1




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users