Check if array is sequential or associative in PHP

There is no build-in way to check if an array is indexed (sequential) or associative in PHP, but you can easily create your own is_associative() function for it.

644 views

Edited: 2021-03-07 10:02

Check if associative array, php

Sometimes it may be useful to know if an array is associative or sequential (indexed); technically there is not really any difference between these two, but functionally it may be easier to loop through an array that only used numbers as keys.

An indexed array is an array where all of the keys are integers. To easily determine the type of array you are dealing with, you can loop through the array while checking if a numeric key is defined — as soon as a undefined value is encountered, you can safely assume that you are dealing with an associative array.

Note. that these examples will only work with single-dimensional arrays; you will need to slightly modify them if you need to handle multidimensional arrays.

Solution:

/**
 * Checks if an array is associative. Return value of 'False' indicates a sequential array.
 * @param array $inpt_arr 
 * @return bool 
 */
function is_associative(array $inpt_arr): bool
{
  // An empty array is in theory a valid associative array
  // so we return 'true' for empty.
  if ([] === $inpt_arr) {
    return true;
  }
  $n = count($inpt_arr);
  for ($i = 0; $i < $n; $i++) {
    if(!array_key_exists($i, $inpt_arr)) {
      return true;
    }
  }
  // Dealing with a Sequential array
  return false;
}

When calling this function you could do like this:

$my_array = ['a' => 'Anna', 'b' => 'Benjamin'];

if (is_associative($my_array)) {
  echo 'Array is associative';
} else {
  echo 'Array is sequential';
}

Output:

Array is associative

Do you need to know the array type?

The question is whether you really need to know the type of an array, since you could iterate over the array, regardless of type, using a foreach loop:

foreach ($some_array as $key => $value) {
    echo PHP_EOL . $key . ':' . $value;
}

Keep in mind that there is not really a difference between associative- and indexed arrays in PHP. You may even choose to use objects instead of arrays if you are working in an OOP context, since objects have other benefits, and properties are supported by the autocompletion feature in some code editors.

In some cases it may be nessecery to check if you are dealing with an associative array, as a function might depend on it to work properly, but in most cases you would probably just assume that the array is formatted correctly.

I had a specific situation where a PHP script was creating a JSON object for JavaScript in the front-end. This script was expecting a JSON object with strings as property names — not hard to see why it was breaking when I provided it with an indexed JSON object instead. To solve this problem, I decided to create it as an associative array in PHP before feeding it to json_encode.

Compare the array with a range-array

You can also use a combination of array_keys and range; this method may seem easier because it does not involve looping, but it is a little bit slower than the first method I covered:

function is_associative(array $inpt_arr)
{
  if ([] === $inpt_arr) {
    return true;
  }

  if(array_keys($inpt_arr) !== range(0, count($inpt_arr) - 1)) {
    return true;
  }
  // Dealing with a Sequential array
  return false;
}

Performance

Of course, performance is probably not your first concern with these simple algorithms, nevertheless, it is still worth a mention.

Depending on the size of your arrays and your system, you may be able to perform more or less than a few millions of these checks in a single second. To conduct a benchmark test of these examples you can try the below code:

$names_array = ['Brian', 'Freddy', 'Gina', 'Johannes', 'Kim'];

$start_time = microtime(true);

for ($x = 0; $x <= 1000000; $x++) {
  is_associative($names_array);
}
$time_spent = microtime(true) - $start_time;

echo $time_spent;

On my old i3 laptop this finishes in 0.17 seconds.

Remember, we you will get the best performance when you count the elements in the array outside of the loop:

$n = count($inpt_arr);
for ($i = 0; $i < $n; $i++) {
  if(!array_key_exists($i, $inpt_arr)) {
    return true;
  }
}

On my old i3 laptop, dong this is about 50 milliseconds faster (~25% faster).

Under normal circumstances you might use isset, but in extremely rare cases a variable might contain the null special value, so using array_key_exists is more safe.

Why use a for loop instead of foreach?

There is rarely any reason not to use a foreach, since the foreach tends to be slightly faster and easier to use. In any case, the performance is almost identical. In this case my reason for using for is functional rather than speed.

I specifically want to check if any of the keys in the array are strings or not in sequence, so using the for loop is just more straight forward.

If you used a foreach in this case, then you need to declare the counter variable before defining the loop, as well as increment the counter inside the loop itself:

$i = 0;
foreach ($inpt_arr as $value) {
  if(!array_key_exists($i, $inpt_arr)) {
    return true;
  }
  $i++;
}

You also have this redundant $value variable which is not really used for anything.

Sequential array vs associative array

PHP does not distinguish between sequential and associative arrays, and that is also why it is difficult to determine, efficiently, the type of array that you are dealing with. In PHP, all arrays are associative arrays, even when the keys only consist of numeric values.

All arrays are not sequential — as you may have noticed, it is possible to fill up an array with randomly placed keys:

$my_array = [
  9 => 'whatever',
  1 => 'something',
  3 => 'and some more stuff',
];

When this happens, the easiest way to traverse the array will be by using the foreach loop:

foreach ($my_array as $key => $value) {
  echo "key: $key\nvalue:$value\n\n";
}

Tell us what you think:

  1. How much faster is C++ than PHP to increment and display a counter in a loop?
  2. How to create a router in PHP that also handles request- methods and parameters.
  3. Detecting the request method used to fetch a web page with PHP, routing, HTTP responses, and more.
  4. How to create a custom error handler for PHP that handles non-fetal errors.
  5. Setting custom HTTP Headers with cURL is useful when changing User Agent or Cookies. Headers can be changed two ways, both using the curl_setopt function.

More in: PHP Tutorials