I’m unable to redim an array with multiple dimensions when testing on any device.
redim someArray(1,4)
///this doesn't work, changes the array's dimensions to (1879152656,8)
///and crashes if you try to use the array after that
Does anyone know some sort of work around for using multi dimensional arrays (that doesn’t include changing them to single-dimension arrays) in an app on a device?
Sort of a big bug, and it’s tricky since it works in the debugger but crashes on devices for me. I’ve already submitted a bug report but no response yet so I’m looking for maybe another way to achieve this in the meantime.
isn’t “Variant” in the sense of Xojo variants.
This is a template class that lets you define a new class Array2d with a specific type, , for all of its member values.
It falls into the realm of “Generics”.
Internally a 2d Array in this class is an array of arrays of whatever type is.
In order to do this in Xojo you’d need to be able to declare something like.
dim arr() as Int()
which of course doesn’t compile
Try this (this is my 10 minute whip it together version so there can be bugs in the code :P)
Class Array2DOfInt
Sub Constructor(rows as integer, columns as Integer)
self.columns = columns
self.rows = rows
contents = new dictionary
for i as integer = 0 to rows - 1
dim tmp() as Integer
redim tmp(columns-1)
contents.value(i) = tmp
next
End Sub
Function operator_subscript(row as integer, column as integer) As integer
if not contents.hasKey(row-1) then
raise new OutOfBoundsException
end if
if column-1 < 0 or column-1 >= columns then
raise new OutOfBoundsException
end if
dim tmp() as integer = contents.value(row-1)
return tmp(column-1)
End Function
Sub operator_subscript(row as integer, column as integer, assigns v as integer)
if not contents.hasKey(row-1) then
raise new OutOfBoundsException
end if
if column-1 < 0 or column-1 >= columns then
raise new OutOfBoundsException
end if
dim tmp() as integer = contents.value(row-1)
tmp(column-1) = v
contents.value(row-1) = tmp
End Sub
Protected columns As Integer
Protected rows As Integer
Protected contents As dictionary
end class
and use it like
[code]dim arr as new Array2DOfInt( 3, 4 )
for row as integer = 1 to 3
for column as integer = 1 to 4
arr(row , column) = 30+row*column // just so we dont have values that could be just the indexes
next
next
dim s as string
for row as integer = 1 to 3
s = s + "row " + str(row)
for column as integer = 1 to 4
dim i as integer = arr(row , column)
s = s + " col " + str(column) + " = " + str(i)
next
s = s + endofline
next
Right I was hoping not to have to do that. I’m trying to share a lot of code and classes between desktop & iOS and currently alllllllll of that code relies on multi-dimensional arrays. I would have to go back and change several hundred lines of code in the desktop apps to be able to do something like this.
I was thinking maybe a way of coming up with my own redim that just creates the array new every time.
Actually Norman, if you examine the code I posted closer you will notice that it is NOT an array of arrays. It is a SINGLE dimension array, where the X,Y coordinates are mathematically converted to a scalar Index…
And yes “T” is a Generic, which is why I said it was “kinda” like a variant
Not Tested… but this should be the translation, or something similar
class Array2D
protected nColumns As Integer
protected nRows As Integer
protected nArray() As Integer
Sub Constructor(columns Integer, rows Integer)
nColumns = columns
nRows = rows
redim nArray(indexOf(rows,columns))
End Sub
Private Function indexOf(column Integer, row Integer) As Integer
dim indx as Integer=((row*nColumns)+column)
If indx<0 Or indx>nArray.Ubound Then
raise new OutOfBoundsException
End If
return indx
End Function
Function subscript(column Integer, row Integer) As Integer
Return nArray(indexOf(column,row)
End Function
Sub subscript(column Integer, row Integer,Assigns newValue as Integer)
nArray(indexOf(column,row) = newValue
End Function
End Class
operator_subscript lets you use standard subscript style notation to access it
there’s very few examples hence why I used that
so you can use it in the same fashion as a real 2d array
[code]dim arr as new Array2DOfInt( 3, 4 )
for row as integer = 1 to 3
for column as integer = 1 to 4
arr(row , column) = 30+row*column // <<<<<<<<< uses operator_subscript (int, int , assigns int)
next
next
[/code]
[quote=200717:@Dave S]Actually Norman, if you examine the code I posted closer you will notice that it is NOT an array of arrays. It is a SINGLE dimension array, where the X,Y coordinates are mathematically converted to a scalar Index…
[/quote]
Indeed it is
[quote=200717:@Dave S]And yes “T” is a Generic, which is why I said it was “kinda” like a variant
[/quote]
… not really but Xojo doesn’t have generics so it is hard to suggest an equivalent concept
[quote=200717:@Dave S]Not Tested… but this should be the translation, or something similar
[code]
class Array2D
protected nColumns As Integer
protected nRows As Integer
protected nArray() As Integer
Sub Constructor(columns Integer, rows Integer)
nColumns = columns
nRows = rows
redim nArray(indexOf(rows,columns)) ///// <<<<<<< I think this is a bug and should be rows * columns
End Sub
in the sim this works with the array 2d code I posted unchanged
[code] dim arr as new Array2DOfInt( 3, 4 )
for row as integer = 1 to 3
for column as integer = 1 to 4
arr(row , column) = 30+row*column // just so we dont have values that could be just the indexes
next
next
dim s as text
for row as integer = 1 to 3
s = s + "row " + row.ToText
for column as integer = 1 to 4
dim i as integer = arr(row , column)
s = s + " col " + column.ToText + " = " + i.ToText
next
s = s + &u0a
next
In the code I posted, just add another function (you will have to name is something other than ReDim ofcourse)
// add noError flag so Redim doesn't cause an exception when increasing size
Private Function indexOf(column As Integer, row As Integer,noError as boolean=false) As Integer
dim indx as Integer=((row*nColumns)+column)
If indx<0 Or (indx>nArray.Ubound And noError=false) Then
raise new OutOfBoundsException
End If
return indx
End Function
Sub myRedim(column As Integer, row As Integer,noError as boolean=false)
ReDim nArray(indexOf(column,row,true)
End Sub