Returning the number of elements in an array

Blitz3D Forums/Blitz3D Beginners Area/Returning the number of elements in an array

jondecker76(Posted 2003) [#1]
What is the easiest way to return the number of elements in a given array?

thanks


Gabriel(Posted 2003) [#2]
Keep track of it when you dimension it?


Insane Games(Posted 2003) [#3]
I don't get it.. Arrays are not resizible. Can you give me an example of what you wanna do ?

Perhapes this will help somehow

; We will create an array with 10 positions, but we wont use them all
; We will only count those that are not empty
Global arraySize = 10
Dim someArray$(arraySize)
someArray$(1) = "this"
someArray$(2) = "is"
someArray$(3) = "one"
someArray$(4) = "way"
someArray$(10) = "wtf"

Print returnSize()

Function returnSize()
	Local counter = 0
	For i = 1 To arraySize
		If someArray$(i) <> "" Then counter = counter + 1
	Next
	Return counter
End Function



Koriolis(Posted 2003) [#4]
Arrays ARE resizable in Blitz. Do another dim on it, and tada, you have resized it.
There is no built-in command to return its current size though, so retaking the example of 'Insane Games', your number of elements is in 'arraySize', and you'll have to set it to the right value by yourself each time you redime the array.


Insane Games(Posted 2003) [#5]
as long as i know, when u do another dim, you loose all the informations.. so, they are not resizeble.. you are just erasing and creating a brand new one (with the same name).

Do the test by yourself..

Dim a$(5)

a$(1) = "If it's resizeble, i'll not loose this information"

Dim a$(3)

Print a$(1)


You could simulate a resize, creating a temporary array, but there are not really sizesible.


jondecker76(Posted 2003) [#6]
thanks guys, that is waht I'm pretty much doing right now - using another variable to track size and using a temp array to retain information. I'm doing this because I use an array of types for a project i'm doing right now, and rather than putting a cap on the information it can hold, I would like it to dynamically resize the arrays at runtime according to how much information it would store. In any case, thanks for your input


Ken Lynch(Posted 2003) [#7]
You don't need an array of types. Just use types if you want dynamic storage.

Types work sort of like a database, so you have a list of records and fields which contain the information. Say I have a type called my type and a variable m.MyType

type MyType
  Field f1, f2, f3
end type

m.MyType = New MyType ; This creates a new type and m points to it
m.MyType = New MyType ; This creates another new type, m now points to this but our first type still exists


We can use types to create a large, dynamic list of data and use just one variable to track it. We can move through the list using

m = After m  ; m points to the next item in the list
m = Before m  ; m points to the previous item in the list
m = First m  ; m points to the first item in the list
m = Last m  ; m points to the last item in the list


You can see types are very powerful, so you shouldn't need an array. Have a look at the Custom Types in the Language Reference for more info.


soja(Posted 2003) [#8]
It would be smart, however, to build an array of types IF you needed an index for quick access. But you don't need to create the array until after you've created all your type instances. Then you just count the type instances and dimension an array for them.


Koriolis(Posted 2003) [#9]
Do the test by yourself.
Thanks, I know. I won't debate on vocabulary issues, it's not the point. You just said "I don't get it...", so I replied to point that as you can "create another array and put it in the same variable" (better like this?), the question of JonD was sensible. Don't you have built-in ways to return the size of an array in some languages? Yes you have. Say in Java by example. You create an array (which is an object), and keep track of it through a reference. You could later on replace it with a new array with a different size. Thus you make the equivalent of a "dim" : create a complete new array and assign it to the reference. Does that mean that there is no need to know the size of the array at a given time? Of course not, as the size of the array pointed by the reference changes in time (in fact the array changes, like in blitz).
The question WAS sensible.


cyberseth(Posted 2003) [#10]
Another road to go down is banks. Banks are resizable without losing data, AND you can find out the size of the bank. If you want to store integers, your values are stored in groups of 4.

myarray = NewArray(100)

For i=0 To 100
    SetArray myarray, i, Rand(5000)
Next

Print GetArray(myarray, 40)
WaitKey()
End

;--------------------------------------
Function NewArray(arraysize)
    arrbank = CreateBank(arraysize*4+4)
    Return arrbank
End Function

Function ReDim(arrbank, newsize)
    ResizeBank arrbank, newsize*4
End Function

Function GetArray(arrbank, iCell)
    Return PeekInt(arrbank, iCell*4)
End Function

Function SetArray(arrbank, iCell, val)
    PokeInt arrbank, iCell*4, val
End Function

Function FreeArray(arrbank)
    FreeBank arrbank
End Function


It's also possible to do multi-dimensional banks, just requires a little math, and you'll need to use the CopyBank method to move the bytes around when resizing, otherwise if you resize the width then all the rows could go out of sync. But it's possible.


Ross C(Posted 2003) [#11]
see when redimentioning an array, why not create an array the same size as the one you have, copy all the data across to it, resize the one needing resized, then copy back across?


roboslug(Posted 2003) [#12]
Warning: partial hijack (and on my first post as well...heh)

Cyberseth,

Nice job. Since you have wrapper functions for this "bank array", you could do multidimensions by storing bank addresses in upper dimensions (the first dimension in a 1x1 points to 2nd bank(N)).

Partially implemented re-work of your code...

myarray = NewArray(100,100)

For i=0 To 50
    For j=0 To 50
       SetArray myarray, i, j, i+j 
       ; easier to check than Rand, result will be dim1+dim2
    Next
Next

Print GetArray(myarray,10,11)

WaitKey()

End



;--------------------------------------

Function NewArray(dim1,dim2)
    arrbank = CreateBank(dim1*4+4)
    For k=0 To dim1
       PokeInt arrbank, k*4,CreateBank(dim2*4+4)
    Next
    Return arrbank
End Function


Function GetArray(arrbank, d1cell,d2cell)
    d2bank = PeekInt(arrbank, d1cell*4)
    Return PeekInt(d2bank,d2cell*4)
End Function


Function SetArray(arrbank,d1cell,d2cell,val)
    d2bank = PeekInt(arrbank, d1cell*4)
    PokeInt d2bank, d2cell*4, val
End Function


I worked out a similar solution, only to easily accomodate bank arrays of different data types I point the bank cells at an address of a Type (using Handle on user defined types for string, array, int, float, bank) and the "type" of the type is specified at creation by the user and used in the supporting functions.

I imagine this uses much overhead and ultimately the thing to do would be more bank manipulation (ie., convert bank cell to string).

Ken,

Not only is quick access a great use of arrays, but if you read up on Blitz arrays (not the Dim style) you will see that it is possible to have local arrays as a field type (even of another type).

Type Object
Field name
Field description
End Type

Type Thing
Field name
Field inventory.Object[100]
End Type

The obvious advantage here is that you can have many "Thing"s that have their own inventory, so even if you have to parse the entire list, it is shorter than searching across (worse case) #_of_Things * #_of_inventories.

The main disadvantage of blitz arrays is that they cannot be resized at all and cannot be returned from a function (they can however be passed into one!), therefore my post is not really on topic.

Cheers!
-Roboslug


Oldefoxx(Posted 2003) [#13]
Good reading, but you guys missed a key point, which I just stumbled upon: Null. It DOES exist in Blitz!

Null
Parameters
None  

Description
Designates a Null Type object. Useful for making a Type variable point to nothing or checking if a Type object exists. Also, useful for checking that there are still objects left on the end of a Type list using the After command. 

Can used for testing and setting. 

See also: Type, After.  

Example
; Null example 

Type Alien 
Field x,y 
End Type 

a.Alien = New Alien 
If a <> Null Then Print "Alien exists!" 
Delete a 
if a = Null Then Print "Alien gone!"  



Koriolis(Posted 2003) [#14]
So?