Detect array dimensions in a particular array programmatically at runtime

If a method is passed a multi-dimensional array how can I find out how many elements (elements x dimensions) it has? The only way I can see is to use trial and error with increasing ubound dimensions. Any tips?

You can use Ubound with a second parameter (1-based) to indicate which dimension you want. For example:

dim ar1( 2, 4 ) as String

dim n1 as integer = ubound( ar1, 1 ) // Gives 2
dim n2 as integer = ubound( ar1, 2 )  //Gives 4

And with API 2.0 you can do this:

Var ar1(2, 4) As String

Var c1 As Integer = ar1.Count(1) // Result is 3
Var c2 As Integer = ar1.Count(2) // Result is 5

Var l1 As Integer = ar1.LastRowIndex(1) // Result is 2
Var l2 As Integer = ar1.LastRowIndex(2) // Result is 4
1 Like

Thanks guys but your examples know the number of dimensions in advance.

1 Like

Looks like I’ll just start counting until I error out.

in a multi dimenion array you can find out how many dimension there are using - uBound :stuck_out_tongue:

dim numDimensions as  integer = whateverArray.Ubound(-1)

Norman, I get an out of bounds on a singe dimension and an “only works for one dimensional arrays” error for multi dimensional when using the extended form. When I use ubound(arr, -1) it’s out of bounds too but ubound(arr,1) works as advertised. So looks like I’m still counting until error.

Documentation suggests that should work
But looking at the replacement it may have been altered and broken ?
Oh and the replacement seems to NOT be able to tell you how many dimensions there are ?

Well I haven’t been able to find it.

Looks like its just broken

Unit tests should have found this … :frowning:

I’ve been programming BASIC since 1980 and can’t understand LastRowIndex anyways. The doc says at

For multi-dimensional arrays, LastRowIndex returns the index of the last row of the dimension you specify, or, if you do not specify a dimension, it returns the value for the first dimension.

My understanding is an array requires all dimensions to be specified to obtain a value. I think the writer is referring to a table columns not an array.

That’s why the keyword is DIm not Var.

1 Like

In 2019r3.1, on Windows (at least) the following code returns 2 in the variable numDims.

Var ary (3, 5) As Integer
Var numDims As Integer
numDims = ary.LastRowIndex (-1)

Even if the array is declared elsewhere and passed to a method, the code seems to return the number of dimensions if the passed LastRowIndex is -1.

That’s probably a bug. As lastrowindex(-1) is invalid and should trow an outpfboundsexception

You should specify the dimension you want the lastindex of, default is 1.

Al least it’s undocumented or i’m overlooking it

If we had generics I could write a generic solution, but we don’t.

Now that is very interesting. Here is the information on ‘dimension’ from the online docs page Arrays.LastRowIndex

Relevant only for multi-dimensional arrays. Used to specify the dimension for which you want the last row index.

The first dimension is numbered 1. If passed a non-existent dimension, it raises an [OutOfBoundsException]( error.

And here is the same thing from the local version of the LR.

Relevant only for multi-dimensional arrays. Used to specify the dimension for which you want the last row.

The first dimension is numbered 1. If passed -1, it will return the number of dimensions in the array. If passed a non-existent dimension, it will cause an [OutOfBoundsException](/OutOfBoundsException) error.

So, is which is the bug? Personally, I would like the online docs to be corrected since the ability to get the number of dimensions might be a useful thing to have. Add in the fact that it seems to work, at least on Windows in 2019r3.1, and it seems like the online docs are the problem.

That’s my opinion…your mileage may vary.

1 Like

i’m not saying it’s a bad feature. it’s a great one actually.
the online docs are not telling about this, that’s a bug or a feature (you’d never know :rofl:)

I don’t see this on Linux 2019r3.2 so the online documentation seems to be what’s supported.

This workaround seems to do the trick:

Function DimensionCount(StringArray as variant)      As integer
	  dim intDimensions as integer
	  dim strArr() as string
	  if StringArray.Type = variant.TypeString + variant.TypeArray then
	    strArr = StringArray //To allow compiler to understand the type
	    While UBound(strArr,intDimensions+1) > -2 //Errors when all dimensions are done
	      intDimensions = intDimensions + 1
	  end if
	    Return intDimensions
	End Function

Please note this is supposed to be a safe-space for citizen devs. If you think you can do better feel free to post away :smiley:

this is supposed to be a safe space for ALL xojo users :slight_smile: