Dynamic Resizing
BlitzMax Forums/BlitzMax Beginners Area/Dynamic Resizing
| ||
Bit tricky to explain this.. plenty of head scratching involved !. I need to indirectly reference an array, so I need something like index[10] But with those 10 array places I need to reference a number of sub references.. kinda like, index[10,5] But the problem is.. although I know the lefthand number ("10") - which is fixed, I dont know how big the sub part is.. ("5") Although I could run though the list, make a note of the total number of arrays needed - it wont be the same for every array.. so there could be alot of wasted space. (lost yet ?) Here's an example of what I'm trying to do: index[1]=1 index[2]=1,2,3,4 index[3]=1,2,3,4,5,6 so although I could use "int index[2,6]" theres alot of wasted space in index[0]. (since it will have room for 6 sub arrays) As I've said though I cant just have them seperate.. int index1[3],int index2[6]..etc Any help please chaps !. |
| ||
Try an array of arrays... Local index[][3] index[0]=[1] index[1]=[1,2,3,4] index[2]=[1,2,3,4,5,6] |
| ||
Thanks Mark. This has to go in a type, to be used in a function though - how do I 'new' the array ? I've got this in my type: field index:int[][] then this in the function: index=new int[][3] But it brings up the error,"Compile Error:Unable to convert from 'Int Array Array' to 'Int'" |
| ||
Tried to do it a slighty different way, I've got a:Type indices Field indices:Int[] End Type In my main type this: Type obj_data Field indexdata:indices[] end type Finally, I'm using this in my function.. obj_ptr.indexdata=New indices[10] obj_ptr.indexdata[0].indices=New Int[4] Which results in a Unhandled Memory error !??? |
| ||
This may be the thing you are looking for:Type ObjectData Field indexdata:indices[0] End Type Type Indices Field indices:Int[0] End Type ' Create a new object of type ObjectData Local objectpointer:ObjectData = New ObjectData ' Resize the array "indexdata" to let it have 10 indexes (0..9) objectpointer.indexdata = objectpointer.indexdata[..10] ' Create a new "indices" object at index 1 of the array "indexdata" objectpointer.indexdata[1] = New indices ' Resize the array "indices" inside the indices type-instance, inside "indexdata" array index 1 objectpointer.indexdata[1].indices = objectpointer.indexdata[1].indices[..5] ' Set a random value from 1 to 100 inside the indices array at index 2, which resides inside the "indexdata" ' array at index 1 objectpointer.indexdata[1].indices[2] = Rand(1, 100) ' Now at index 1 of array "indexdata", there's an array with 5 indexes (0..4) ' Create a new "indices" object at index 2 of the array "indexdata" objectpointer.indexdata[2] = New indices ' Resize the array "indices" inside the indices type-instance, inside "indexdata" array index 1 objectpointer.indexdata[2].indices = objectpointer.indexdata[1].indices[..20] ' Set a random value from 1 to 100 inside the indices array at index 12, which resides inside the "indexdata" ' array at index 1 objectpointer.indexdata[2].indices[12] = Rand(1, 100) ' Now at index 2 of array "indexdata", there's an array with 20 indexes (0.19) PrintData(objectpointer, 1, 2) PrintData(objectpointer, 2, 12) Function PrintData(a:ObjectData, x, y) Print a.indexdata[x].indices[y] End Function |
| ||
And with this :Type toto Field index:Int[][] Method Init(val:Int, val1:Int) index=index[..val+1] index[val]=index[val][..val1] End Method End Type ' We create a new type toto ex:toto=New toto ' We initialize first array to 0 (1 index) and second array to 0-2 (3 index) ex.Init(0,3) ' We assign the 3 values to array [0] because there is space for 3 values in the second array ex.index[0]=[1,2,3] ' Assign 3 values to the first array index 0 ' Print result Print ex.index[0][0] Print ex.index[0][1] Print ex.index[0][2] Print ' Now we need 5 values in the second array. ' We resize this array. ex.Init(0,5) ' We assign value 4 and 5 (you need to assign new value one by one) ex.index[0][3]=4 ; ex.index[0][4]=5 ' Print result Print ex.index[0][0] Print ex.index[0][1] Print ex.index[0][2] Print ex.index[0][3] Print ex.index[0][4] You need to index the first array before init the second array. Array[][] indicate array is created but not sized, return an error. You can do this : First assign an array [0][] or First assign an array [2][] or First assign an array [0][10] or First assign an array [2][10] No importance since the first array is initialized. More compact, no pointer. |
| ||
A complete example (expanding on my previous code):Type ObjectData Field indexdata:indices[] End Type Type Indices Field indices:Int[] End Type SeedRnd(MilliSecs()) ' Create a new object of type ObjectData Local objectpointer:ObjectData = New ObjectData ' Resize the array "indexdata" to let it have 10 indexes (0..9) objectpointer.indexdata = objectpointer.indexdata[..10] ' Create new "indices" objects at all indexes of the array "indexdata" For i = 0 To 9 objectpointer.indexdata[i] = New indices Next ' Resize array "indices" for all "indices"-type-instances and set a random number for all of them For i = 0 To (objectpointer.indexdata.length - 1) ' Resize the array "indices" at each index of array "indexdata" to a random size between 1 and 10 objectpointer.indexdata[i].indices = objectpointer.indexdata[i].indices[..Rand(1, 10)] ' Set a random value from 1 to 100 inside the indices array at each index, ' which resides inside the "indexdata" array at each index For j = 0 To (objectpointer.indexdata[i].indices.length - 1) objectpointer.indexdata[i].indices[j] = Rand(1, 100) Next Next ' Print all data For i = 0 To (objectpointer.indexdata.length - 1) For j = 0 To (objectpointer.indexdata[i].indices.length - 1) PrintData(objectpointer, i, j) Next Print Next Function PrintData(a:ObjectData, x, y) Print "objectpointer.indexdata[" + x + "].indices[" + y + "]: " + a.indexdata[x].indices[y] End Function |
| ||
@ extron: I've expanded your code too to this: Type toto Field index:Int[][] Method Init(val:Int, val1:Int) index=index[..val+1] index[val]=index[val][..val1] End Method End Type SeedRnd(MilliSecs()) ' We create a new type toto ex:toto=New toto ' We initialize first array to 10 (indexes 0..9) and second array to a random size (from 1 to 10) For i = 0 To 9 ex.init(i, Rand(1, 10)) Next ' Fill each index with a random number For i = 0 To (ex.index.length - 1) For j = 0 To (ex.index[i].length - 1) ex.index[i][j] = Rand(1, 100) Next Next ' Print all numbers For i = 0 To (ex.index.length - 1) For j = 0 To (ex.index[i].length - 1) Print "ex.index[" + i + "][" + j + "]: " + ex.index[i][j] Next Print Next Now you have two fully working examples which you can use, PaulJG. But I have to admit, Extron's code is easier to understand and follow. |
| ||
And I want also to thank PaulJG for supplying this problem, because I was actually looking for some similar code. I want to create a spacesim, where a datafile stated how many space-sectors there are, how many stations each sector has, and how many commodities each station has. Each station can have a different number of commodities, and each sector can have a different number of stations. I was creating code with types, which have arrays, where each index points at another type, which also had arrays (like my first expanded code at this thread). Now I'm using Extron's approach and reduced my code significantly. Now I can do: "Universe.NewStation", which automatically adds a new station to the last added sector. When I do "Universe.NewCommodity", this adds a new commodity to the last added station, which was last added to a sector. Type TUniverse Field NumSec% Field ASectors:TSector[] Field NumStat% Field AStations:TStation[][] Field NumComm% Field AComm:TCommodity[][][] Method NewSector() ' Set variables (increase sectornumber and reset all others) NumSec% = NumSec% + 1 NumStat% = 0 NumComm% = 0 ' Resize the "ASectors"-array to include a new sector ASectors = ASectors[..NumSec%] ' Also preset first index of AStations to have the same number of indexes as there are sectors AStations = AStations[..NumSec%] ' Create a new "TSector"-type-instance at this new "ASectors"-index ASectors[NumSec% - 1] = New TSector ' Load data into this new type-instance from the "Universe.txt" datafile LoadSectorData(ASectors[NumSec% - 1]) End Method Method LoadSectorData(SectorPointer:TSector) ' Temporary loadroutine (sets a name for the sector) SectorPointer.Name$ = "Sector " + NumSec% End Method Method NewStation() ' This method creates a new station inside the last sector ' Set variables (increase stationnumber and reset others) NumStat% = NumStat% + 1 NumComm% = 0 ' Resize the "AStations"-array to include a new station AStations[NumSec% - 1] = AStations[NumSec% - 1][..NumStat%] ' Also preset first and second indexes of Acomm to have the same number of indexes as there ' are sectors and stations AComm = AComm[..NumSec%] AComm[NumSec% - 1] = AComm[NumSec% - 1][..NumStat%] ' Create a new "TStation"-type-instance at this new "AStations"-index AStations[NumSec% - 1][NumStat% - 1] = New TStation ' Load data into this new type-instance from the "Universe.txt" datafile LoadStationData(AStations[NumSec% - 1][NumStat% - 1]) End Method Method LoadStationData(StationPointer:TStation) ' Temporary loadroutine (sets a name for the station) StationPointer.Name$ = "Station " + NumStat% End Method Method NewCommodity() ' This method creates a new commodity inside the last station, which is inside the last sector ' Set variables (increase commoditynumber) NumComm% = NumComm% + 1 ' Resize the "AComm"-array to include a new commodity AComm[NumSec% - 1][NumStat% - 1] = AComm[NumSec% - 1][NumStat% - 1][..NumComm%] ' Create a new "TCommodity"-type-instance at this new "AComm"-index AComm[NumSec% - 1][NumStat% - 1][NumComm% - 1] = New TCommodity ' Load data into this new type-instance from the "Universe.txt" datafile LoadCommodityData(AComm[NumSec% - 1][NumStat% - 1][NumComm% - 1]) End Method Method LoadCommodityData(CommodityPointer:TCommodity) ' Temporary loadroutine (sets a name for the commodity) CommodityPointer.Name$ = "Commodity " + NumComm% End Method End Type Type TSector Field Name$ End Type Type TStation Field Name$ End Type Type TCommodity Field Name$ End Type SeedRnd(MilliSecs()) ' Add a random number of sectors, which all have a random number ' of stations, which in turn all have a random number of commodities Universe:TUniverse = New TUniverse For i = 0 To Rand(1, 10) Universe.NewSector() For j = 0 To Rand(1, 10) Universe.NewStation() For k = 0 To Rand(1, 10) Universe.NewCommodity() Next Next Next ' Print all names of all sectors, stations and commodities inside the universe For i = 0 To (Universe.ASectors.length - 1) Print Universe.ASectors[i].Name$ For j = 0 To (Universe.AStations[i].length - 1) Print " " + Universe.AStations[i][j].Name$ For k = 0 To (Universe.AComm[i][j].length - 1) Print " " + Universe.AComm[i][j][k].Name$ Next Print Next Print Next Now all code is inside the TUniverse type. Previously all code existed in separate types. The loading routines must be included next, but I don't expect any problems here. I was searching for the same thing, a multidimensional array with a dynamically secondary index (or how would you call it). So you see, helping others can help yourself too. This thread certainly helped my own project. |
| ||
Good if it can help. I also give a solution in this thread : http://www.blitzbasic.com/Community/posts.php?topic=42327 Good luck in your project. ;) |
| ||
Big thanks to you both ! :) |