Android Question An ARRAY or problems, or should I say a problem with an ARRAY

JamesGreaves

Active Member
Licensed User
I need to have a two-dimensional array that can be accessed from all modules.
The trouble is, I will only know how big it needs to be at runtime.
I know I cannot REDIM the array so the alternative is to create a large enough array accommodate for all possibilities.
(Unless someone else can advice me otherwise)
If I do have to go with that option then I need to understand how big can I go?
Is an array Data(300,300) as Double going to be a problem?
 

JamesGreaves

Active Member
Licensed User
In line with this then, is it true that I cannot create an array at runtime which can be accessed from all modules?
 

DonManfred

Expert
Licensed User

emexes

Well-Known Member
Licensed User
I need to have a two-dimensional array that can be accessed from all modules.
The trouble is, I will only know how big it needs to be at runtime.
That should be ok. You can declare it without specifying the size, and then later in the code, when you do know the size, Dim it then. I know that I have done this, but now I am wondering: did I only do it with one-dimensional arrays?...
I know I cannot REDIM the array so the alternative is to create a large enough array accommodate for all possibilities.
But you can always write your own CustomRedim function that takes an existing array + new dimensions as parameters, and creates a new (larger) array, copies the existing array across, and returns it via the function return value. I am pretty sure I've done that, but again I am wondering: did I only do it with one-dimensional arrays?...
B4X:
Sub ResizeDoubleArray2(E() As Double, OldSize1 As Int, OldSize2 As Int, NewSize1 As Int, NewSize2 As Int) As Double()

    Dim N(NewSize1, NewSize2) As Double

    For I1 = 0 to Min(OldSize1, NewSize1) - 1
        For I2 = 0 To Min(OldSize2, NewSize2) - 1
            N(I1, I2) = E(I1, I2)
        Next I2
    Next I1

    Return N

End Sub
It might be possible to get the sizes of the existing array from the array itself, but... I don't have B4A ready to run at the moment to test that theory.

Also, you might need to put a comma in the ()'s to indicate that they are two-dimensional arrays.
 

emexes

Well-Known Member
Licensed User
Thank you. I am going to go with a LIST of LISTS with this one.
No worries. Lists of lists have pros and cons cf 2d arrays. Main con is accessing items using two steps of .Get functions rather one step of () indexing. Perhaps have a quick play around with that, before making the final decision.
 

Jack Cole

Active Member
Licensed User
You can get around the con by writing a function that makes it behave like an array. For example, you could call it Get2D(xval as int, yval as int) as double. Then have that function perform the 2 gets.
 

Jack Cole

Active Member
Licensed User
Here is another solution that I have developed for an app that I needed to reference a flexible 2D grid. It takes a 1D list and treats it like it is 2 dimensional. The nice thing about this approach is that it is easier to save and restore.

B4X:
Sub ListToXY(l As List, x As Int, y As Int, TotalColumns As Int, TotalRows As Int, HorizStacked As Boolean) As String
    ''Log("ListToXY")
    If HorizStacked Then
        Return l.Get(x+y*TotalColumns)
    Else
        Return l.Get(y+x*TotalRows)
    End If
End Sub
 

thetahsk

Active Member
Licensed User
I need to have a two-dimensional array that can be accessed from all modules.
..
if you like a very handy solution, use the EJM - Efficient Java Matrix Library
https://www.b4x.com/android/forum/threads/ejml-efficient-java-matrix-library.27030/

B4X:
    ....
    'https://www.b4x.com/android/forum/threads/ejml-efficient-java-matrix-library.27030/
    Dim SM As SimpleMatrix
    'SM.LoadBinary(path_file_name)
    SM.Initialize(30,30)
      
    For row=0 To SM.NumRows-1
        For col=0 To SM.NumCols-1
            SM.SetElement(row,col,Sqrt(col*row))   'fill every element
        Next
    Next
   
    Log(SM.GetElement(5,5))
    Log(SM.NumCols)
    Log(SM.NumRows)
  
   
    'Redim
    SM.Initialize(15,5)
    SM.SetDouble(1.4142136)
    Log(SM.ToString)
 
Last edited:
Top