Android Question 2D arrays

ShepSoft

Member
Licensed User
This compiles without error:
B4X:
Sub dbg As String(2,2)
    Public strArr(2,2) As String
    strArr(1,1) = "Hello world!"
    Return Array(strArr)
End Sub
However I cannot work out the syntax to access the return value.
This doesn't work:

because the Array keyword is returning a single dimension array - so how do I return a 2D array ?
There doesn't seem to be much to go on: a search of the forums reveals nothing, the documentation has nothing, and the video on Arrays says nothing.
Can anyone help ?
 
Last edited:

emexes

Expert
Licensed User
This B4J sample seems to do what you need, except that the array size is not constant by declaration at 2 x 2.
B4X:
Sub dbg(SampleParameter As String) As String(,)

    Public strArr(2,2) As String
    strArr(1,1) = SampleParameter

    Return strArr

End Sub

Dim RA(,) As String = dbg("Hello, world!")

Log(RA.Length)    'hmm... but *which* dimension?  and how to get length of other dimension?

For I = 0 To 1
    For J = 0 To 1
        Log(I & " " & J & " = """ & RA(I, J) & """")
    Next
Next

Log("""Bonus"" = """ & dbg("Goodbye, cruel world!")(1, 1) & """")

 
Last edited:
Upvote 0

ShepSoft

Member
Licensed User
Thanks very much emexes.
I found that this works - a lone comma providing the answer:
2D ARRAY:
Sub dbg As String(,)
    Public strArr(2,2) As String
    strArr(1,1) = "Hello world!"
    Return strArr
End Sub
but it's a shame it's not mentioned in the all too brief documentation.
 
Upvote 0

emexes

Expert
Licensed User
it's a shame it's not mentioned in the all too brief documentation.
I feel like I did see it somewhere, possibly alongside a mention of multi-dimension arrays actually being arrays-of-arrays or something like that.

Did you spot the bonus bit where you can add the array indices directly to the dbg() call? I use that quite a bit when calling ByteConverter functions. ?
 
Upvote 0

ShepSoft

Member
Licensed User
Yes I had realised that - thanks. The saving grace for B4 is having a good support community.
 
Upvote 0

ShepSoft

Member
Licensed User
For the record .....

Subs and multi-dimensional arrays

The trick with multi-dimensional arrays is knowing when - and when not - to use explicit dimension sizes.

To pass a multi-dimensioned array into a Sub you could use this syntax:
B4X:
Sub dbgIn(p(,) As String)
    Log(p(1,1))
End Sub
which will work but it is clear that it is unsafe because the Log line is guessing the dimensions.
So will this work ?
B4X:
Sub dbgIn(p(2,2) As String)
    Log(p(1,1))
End Sub
No it won't - as the Intellisense help for Subs says - we can't pass explicit dimensions. We'll get an "Object reference not set to an instance of an object" error. Instead, we need to use the 'lonely comma/s' syntax but check the dimensions before accessing the array. Unfortunately, we have to use the Reflection library (or dig into the Java) to get them. We can do something like this:
B4X:
Sub dbgIn(p(,) As String)
  Dim r As Reflector
  Dim dims(0) As Int
  r.Target = p
  dims = r.TargetRank
  If dims(0)>=1 And dims(1)>=1 Then
    Log(p(1,1))
  End If
End Sub
which will work and is safer.

To do the reverse and return a multi-dimensional array from a Sub we can do this:
B4X:
Sub dbgOut As String(,)
    Public strArr(2,2) As String
    strArr(1,1) = "Out world!"
    Return strArr
End Sub
This example creates a 2D array within the Sub and returns it from the sub. Note that you must explicitly declare the array dimensions when you create it within the body of the Sub - using a lonely comma will cause an error when you try to access it.

To access the returned array you can do this:
B4X:
    Dim dout(,) As String = dbgOut
    Log(dout(1,1))
or you can also simply do this:
B4X:
  Log(dbgOut(1,1))

I hope this might be helpful.
 
Upvote 0

emexes

Expert
Licensed User
but check the dimensions before accessing the array. Unfortunately, we have to use the Reflection library (or dig into the Java) to get them.
Or just try access the array anyway:
B4X:
Sub dbgIn(p(,) As String)
    Try
        Log( p(1, 234) )

    Catch
        Log("Nice try, no cigar!")

    End Try
End Sub
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…