I have a function that has to accept an array of points, or an array of array of points (a 2 or 3 dimensional array). I’m looking for an reliable way to detect whether it has 2 or 3 levels. The thing is, I cannot count on the keys of the arrays to do the checking, so this wont work:
$levels = isset($array[0][0]) && is_array($array[0][0]) ? 3 : 2;
..as the first key might not be 0. It usually is, but I don’t want to rely on this. And anyways, it’s an crappy and a close minded way to do that. Optimally, I would like to check for any number of levels without having to loop through the whole array.
Here’s what the arrays might look like:
array(5) {
[2] => array(2) {
[x] => 3
[y] => 6
}
[3] => array(2) {
[x] => 4
[y] => 8
}
...
And a three dimensional array would contain these arrays.
Some notes:
- The arrays are large, so completely looping through the arrays is not a very good option
- The arrays are numerically and sequentially indexed (with the exception of the last level, which has x and y)
- The array keys might or might not start from 0
While writing this, I came up with a solution that might be feasible; a recursive function that checks the first item of an array, if it is, then call itself on the newly found array etc.
Are there any better, cleaner ideas? Bonus points for supporting arrays that might have both scalar values and arrays (eg. the first item of an array might be a string, but the next is an array).
If you expect a complete array or a complete array of arrays then you could try:-
If however your array is sparse its more difficult.
The basic problem is that a php “array” is actually a one dimensional hash. The trick being that a value can be another “array”. So you need to access to second level to determine whether its a value or an array.
Again if you expect a given array to contain only point values, or only other arrays you only need to check one entry so:
Should get you what you want: the current() function returns the current array pointer (which defaults to the first – so it will always be set to something), so the inside current($points) would get you $points[0] or the first entry with an actual value, likwise the outside current will get you something like $points[0][0].