Two Dimensional Arrays - SOLVED!

Monkey Forums/Monkey Beginners/Two Dimensional Arrays - SOLVED!

chimaera(Posted 2014) [#1]
Hi,

I know that this is not a new topic on these forums, but after looking through some of the answers I still can't wrap my head around an easy way to create multi dimensional arrays. Hope fully someone can help me.

I simply want to create a 2 dimensional array that has a length of 255.

To create a single dimensional array I would do this (and it works):
myArray:int[]
myArray=New int[256]

How would I go about declaring and initiating a two dimensional array based on the above syntax or "logic"?


Supertino(Posted 2014) [#2]
Example - I mostly use for tile maps.
Global Width:Int=12
Global Height:Int=8
Global myArray:Int[][]

myArray = AllocateArrayInt(Width,Height)
myArray[3][5] = 7
myArray[5][3] = 3

For Local x:Int = 0 Until myArray[0].Length
For Local y:Int = 0 Until myArray[1].Length
	Print myArray[x][y]
Next
Next


Functions
Function AllocateArrayInt:Int[][]( i:Int, j:Int)
    Local arr:Int[][] = New Int[i][]
    For Local ind = 0 Until i
        arr[ind] = New Int[j]
    Next
    Return arr		
End

Function AllocateArrayString:String[][] (i:Int, j:Int)
    Local arr:String[][] = New String[i][]
    For Local ind = 0 Until i
        arr[ind] = New String[j]
    Next
    Return arr		
End



chimaera(Posted 2014) [#3]
Thanks for the answer Supertino! I will try it.

But just for discussions sake. you answer also shows how weird the array declaration and initiating really is, and I for one can't see why it should be this complicated. I should be able to write something along the lines of "local myArray:int[256,2] = New int[][]" to create an array with X amount of slots with Y amount of dimensions containing ints. Your solution works, but I see it as a work around rather than a language solution. Iterating through a each index creating a new int the array (which already is stated that it should only contains ints) to initiate them just sounds....a bit wonky. This should happen "behind the curtains" so to say. (This is not at all criticism to your solution, Supertino)

Maybe there is a valid reason why it is so complicated (or at least not as straightfoward as I would like) that I do now know about. Any insights into this, Mark?

Thanks again for the answer! Much appreciated.


chimaera(Posted 2014) [#4]
Just tested your solution and will work great for my implementation. Thanks!


Gerry Quinn(Posted 2014) [#5]
The generic approach:



So if you wanted to make a rectangular 2D array of new Point objects, you could write:

Local myArr:Point[][] = Generic< Point >.AllocateArray( 7, 3 )
Generic< Point >.FillObjectArray( myArr )

If it was an array of ints, you wouldn't use a fill command because the array will be full of zeros anyway. With the Points all the values are null after the first command. The second command replaces each null with a new Point. Of course you could fill it another way, but sometimes it's nice to have non-null objects guaranteed from the start.

The reason it's this way is that - I think for memory protection purposes - many of the target languages work this way. A minor advantage is that your arrays don't need to be rectangular, though I doubt this is used often.

You can easily enough make fake C-style arrays using 1D arrays - there's some code around for that,, I know. It has some advantages if you are doing heavy calculations.


tiresius(Posted 2014) [#6]
If you think of 2D as an array of arrays you get closer to understanding.
It is not very BASIC-like but it does make sense and with helper functions like Gerry provides you stop worrying about it anymore.

Think about what the language requires, you need to declare an array of arrays, and then you need to create the new arrays (via New) within the array.
Have a beer.


Danilo(Posted 2014) [#7]
Playing with different syntax styles, derived from Gerry Quinn's generics.
Strict

Class Array1D< T >
    Function Create:T[](dimensions:Int)
        Return New T[dimensions]
    End
End

Class Array2D< T >
    Function Create:T[][](dimension1:Int, dimension2:Int)
        Local arr:T[][] = New T[ dimension1 ][]
        For Local index:Int = 0 Until dimension1
            arr[ index ] = Array1D< T >.Create( dimension2 )
        Next
        Return arr
    End
End

Class Array3D< T >
    Function Create:T[][][](dimension1:Int, dimension2:Int, dimension3:Int)
        Local arr:T[][][] = New T[ dimension1 ][][]
        For Local index:Int = 0 Until dimension1
            arr[ index ] = Array2D< T >.Create( dimension2, dimension3 )
        Next
        Return arr
    End
End


Function Main:Int()
   Local myArray1:Int[] = Array1D<Int>.Create(256)
   
   myArray1[2] = 1
   Print myArray1[2]
   Print myArray1.Length


   Local myArray2:Int[][] = Array2D<Int>.Create(10,10)
   
   myArray2[2][2] = 12
   Print myArray2[2][2]
   Print myArray2.Length


   Local myArray3:Int[][][] = Array3D<Int>.Create(10,10,10)
   
   myArray3[2][2][2] = 123
   Print myArray3[2][2][2]
   Print myArray3.Length

   Return 0
End


Strict

Class ArrayOf< T >
    Function Create:T[](dimensions:Int)
        Return New T[dimensions]
    End

    Function Create:T[][](dimension1:Int, dimension2:Int)
        Local arr:T[][] = New T[ dimension1 ][]
        For Local index:Int = 0 Until dimension1
            arr[ index ] = ArrayOf< T >.Create( dimension2 )
        Next
        Return arr
    End

    Function Create:T[][][](dimension1:Int, dimension2:Int, dimension3:Int)
        Local arr:T[][][] = New T[ dimension1 ][][]
        For Local index:Int = 0 Until dimension1
            arr[ index ] = ArrayOf< T >.Create( dimension2, dimension3 )
        Next
        Return arr
    End
End


Function Main:Int()
   Local myArray1:Int[] = ArrayOf<Int>.Create(256)
   
   myArray1[2] = 1
   Print myArray1[2]
   Print myArray1.Length


   Local myArray2:Int[][] = ArrayOf<Int>.Create(10,10)
   
   myArray2[2][2] = 12
   Print myArray2[2][2]
   Print myArray2.Length


   Local myArray3:Int[][][] = ArrayOf<Int>.Create(10,10,10)
   
   myArray3[2][2][2] = 123
   Print myArray3[2][2][2]
   Print myArray3.Length

   Return 0
End


Maybe rename Create() to Dim():
Local myArray1:Int[]     = ArrayOf<Int>.Dim(256)
Local myArray2:Int[][]   = ArrayOf<Int>.Dim(100,100)
Local myArray3:Int[][][] = ArrayOf<Int>.Dim(10,10,10)

Just syntactic sugar. ;)