How to initialize a 2 dimension array ?
Monkey Forums/Monkey Programming/How to initialize a 2 dimension array ?
| ||
Hi there, I have a class with a field such : Field data:T[][] ' The internal representation of the grid. And then i want to initialize the data array in the constructor. But i dunno how to do that. I though it was : Self.data = New T:[width][height] But it doesnt seem to work. I suspect the "New T" to not working in Monkey. T is a generic. Any ideas ? Thanks! |
| ||
I think i found the solution.Self.data =[New T[width], New T[height]] |
| ||
You could try this: [monkeycode] 'summary: init a 2d array Function CreateArray:T[][](rows:Int, cols:Int) Local a:T[][] = New T[rows][] For Local i:Int = 0 Until rows a[i] = New T[cols] End Return a End[/monkeycode] |
| ||
Yeah however this would require a loop. The idea was to get the array ready when the grid is built. However, i will use your exemple for a grid reset method. Thanks! :) |
| ||
however your post no 2 will not give you the results you are looking for. :) [edit] that example will produce an array with two columns. one column of length "width" and the other of length "height". |
| ||
I have already answer to a similar post but it was not with a constructor. but sometime simple solution are good one. |
| ||
Or just use a single dimensioned array and calculate the x/y position manually:Local width:int = 7 'examples Local height:Int = 5 'examples Local myarray:Int[width * height] Local index:int Local x:int Local y:int 'assuming a particular x/y coordinate in the grid where x/y go from 0 to width-1, height-1 index = x + y * width 'and to go back from the index to an x/y coordinate: x = index mod width y = (index - x) / width |
| ||
Multi-dimensional arrays in Monkey require a loop whether you like it or not. A 2D array is a 'thing' (it's not exactly an object, but it must be 'constructed' like one) that contains a collection of 1D arrays, each of which must be individually 'constructed'. Then each 1D array contains a collection of whatever you wanted to put in your array. If those are objects (as distinct from primitives like ints) they must be constructed too. So loops are more-or-less inescapable. Making a template like therevills suggests above is the best approach. [Depending on what you are planning, you might want to construct the individual objects too - the code above generates an array of nulls.] |
| ||
I know they require a loop but for initialization i think it is a bit overkill. I mean what wrong with : Field data:T[][] = New T:[width][height] I think it do exactly what its supposed to do which is initialize an array of array of T. The result gonna be.. if you take this code : Field data:T[][] = New T:[4][4] The result are : [0][1][2][3][4] ^ ^ ^ ^ ^ [0][0][0][0][0] [1][1][1][1][1] [2][2][2][2][2] [3][3][3][3][3] [4][4][4][4][4] That why i see the first array as the width then the other array as the height. So if your doing data[1][2] You get the second col and the third row (since its based on 0) Local myarray:Int[width * height] Is the same thing as my exemple. (See http://stackoverflow.com/questions/1242705/performance-of-2-dimensional-array-vs-1-dimensional-array) its just that i find the 2D array a bit less confusing when it come to indexing that is when you talk about a grid. |
| ||
however your post no 2 will not give you the results you are looking for. :) [edit] that example will produce an array with two columns. one column of length "width" and the other of length "height". Why ? Sorry but i believe it actually do exactly what im looking for. :) it is initializing the first array as an array of T of width in size then for the second array an array of T of height in size. Which is perfect for the representation of a grid. (Well at least to me) |
| ||
Why ? Sorry but i believe it actually do exactly what im looking for. :) it is initializing the first array as an array of T of width in size then for the second array an array of T of height in size. Which is perfect for the representation of a grid. (Well at least to me) The number of elements in a grid is width*height. What you have done is to create enough elements for width PLUS height. A loop is the best way to generate a grid structure in an array-of-arrays situation. Personally I tend to avoid them altogether; just create a [width*height] array and index it with (x+y*width). Additional: Monkey does not have "multi-dimensional arrays", it has "arrays of arrays". There's a big difference. |
| ||
In monkey, if you want to create a 2 dimensional array, you will have to do it with a function like therevills posted. Even Mark Sibly, the creator monkey suggested to do it that way, he should know it best. What is it that you don't like about the solution offered? |
| ||
rushibno said: "I mean what wrong with : Field data:T[][] = New T[width][height]" What's wrong is that it doesn't work that way in Monkey, perhaps in part because it doesn't work that way in many of Monkey's target languages. On the plus(?) side, you could make a triangular array in Monkey if you wanted - you are not confined to rectangles! Just make a function like therevills said, and then you can initialise an array in one line in Monkey too. |
| ||
@matty it's exactly the simple but so efficient solution i also use. |
| ||
Btw, muddy_shoes wrote a great article on array performance (specifically 1d vs 2d): http://pointlessdiversions.blogspot.co.nz/2012/05/1d-vs-2d-arrays-performance-reality.html |
| ||
Thanks for this link Shinkiro1, it's a fine analyze. |
| ||
Thanks all for your replies. Nice article Shinkiro. I see now why its better a 1d array. I was sure i could use a 2d array but well. I haven't taken care of the target. I will go the 1dim array route then. Its not much of a change anyway.. its just because i found the 2dim array more intuitive. Also i was wondering would it be harder to add a third dimension to a 1dim array ? |
| ||
More dimension you need less 1D adaptation is easy. If you dont need particular performance you'll probably feel better with 2D array using. In another hand, if you make your own conversion formula it's clear as crystal. (tab_in(x,y) , tab_out(x,y)) |
| ||
I think its.. ( (row * height) + (col * width)) * 3 + depth |
| ||
Arghh .. the point of the article is that it really doesn't matter from a performance standpoint if you use a 1D or 2D array (except for some cases). Personally I prefer to use a 2D array, as for me it's much easier to read such code. [monkeycode] mapArray[3][4] = 10 [/monkeycode] |
| ||
Why are you angry ? :P |
| ||
I think there is a real performance difference in some predictable circumstances. I got a consistent speed boost by a factor of almost two when I implemented the Dijkstra algorithm using a 1D array instead of 2D. And the code was shorter, because a 1D array is indexed with ints instead of tuples, so when you are remembering a list of locations you have less to do. However, a factor of two even in an important algorithm would probably not break any game. All in all, there is little reason not to use 2D if that's what you prefer. |
| ||
I agree with you Gerry, even if 1D performance are better, users must use what they prefer. If they use 2D and need performance they still can modify source. Users must not be crystallized in a restrictive dimension or criticised for their dimension critical choice. |
| ||
That why i think i should go the performance route but that only for my needs since im going to use pathfinding. Also i realised i needed a 3D array which make things worse. |
| ||
Lets consider a 3D volume is a superposition of 2D arrays and you'll find a solution. method: In 1D for an element X1 you have direct access to tab_in[X1] and tab_out[X1] in 2D for an element (X2,Y2) you have classic formula tab_in[f(X2,Y2)] and tab_out[f(X2,Y2)] f(X2,Y2) return an element X1 wich give you 1D tab direct acces in 3D for an element (X3,Y3,Z3) you have to found a formula considering a superposition of 2D arrays lets call it g(X3,Y3,Z3) wich return you an element(X2,Y2) usable with function f and finally obtain X1. (You can use this step to verify your formula.) After what by a composition of function f and g you will find the direct h function wich transform (X3,Y3,Z3) directly to a single X1 I think h is a kind of function like : f(X3,Y3)+Z3*step with step=2D array size |