How To Check If A PHP Array Is Associative Or Sequential?

Published October 12, 2024

Problem: Identifying Array Types in PHP

Arrays in PHP can be associative or sequential. Telling these types apart is sometimes needed for correct data handling. Determining the array type in code can be difficult, as PHP doesn't have a built-in function for this task.

Solution: Checking Array Types in PHP

Using array_is_list() Function (PHP 8.1+)

PHP 8.1 introduced the array_is_list() function to check if an array is sequential. This function returns true if the array has integer keys that start from 0 and increase sequentially.

To use array_is_list(), pass your array as an argument:

$sequential = ['apple', 'orange', 'tomato'];
$associative = ['fruit1' => 'apple', 'fruit2' => 'orange'];

var_dump(array_is_list($sequential)); // Output: bool(true)
var_dump(array_is_list($associative)); // Output: bool(false)

Tip: Handling Mixed Arrays

Be careful with mixed arrays. If an array contains both sequential and associative elements, array_is_list() will return false. For example:

$mixed = [0 => 'apple', 'fruit' => 'orange', 2 => 'banana'];
var_dump(array_is_list($mixed)); // Output: bool(false)

Custom Function for Older PHP Versions

For PHP versions before 8.1, you can create a custom function to check if an array is a list:

if (!function_exists('array_is_list')) {
    function array_is_list(array $arr)
    {
        if ($arr === []) {
            return true;
        }
        return array_keys($arr) === range(0, count($arr) - 1);
    }
}

This custom function first checks if the array is empty (which is considered a list). If not, it compares the array keys with a range of numbers from 0 to the array length minus 1.

To make your code work with both older and newer PHP versions, wrap the custom function in a function_exists() check:

if (!function_exists('array_is_list')) {
    // Custom function implementation
}

// Now you can use array_is_list() regardless of PHP version
$result = array_is_list($yourArray);

This approach allows you to use array_is_list() in your code, regardless of the PHP version running on the server.

Testing Array Types

Examples of Array Type Checking

To show how to check array types using the array_is_list() function, here are some examples:

// Testing empty arrays
$emptyArray = [];
var_dump(array_is_list($emptyArray)); // Output: bool(true)

// Testing sequential arrays
$sequentialArray1 = ['apple', 'orange', 'banana'];
$sequentialArray2 = [0 => 'red', 1 => 'green', 2 => 'blue'];
var_dump(array_is_list($sequentialArray1)); // Output: bool(true)
var_dump(array_is_list($sequentialArray2)); // Output: bool(true)

// Testing associative arrays
$associativeArray1 = ['fruit' => 'apple', 'color' => 'red'];
$associativeArray2 = [1 => 'first', 0 => 'second', 2 => 'third'];
var_dump(array_is_list($associativeArray1)); // Output: bool(false)
var_dump(array_is_list($associativeArray2)); // Output: bool(false)

In these examples, we can see that:

  • Empty arrays are lists.
  • Sequential arrays with numeric keys starting from 0 are lists.
  • Associative arrays with string keys or non-sequential numeric keys are not lists.

The order of numeric keys matters. Even if all keys are numeric, if they're not in order starting from 0, the array is not a list:

$nonSequentialNumeric = [2 => 'a', 0 => 'b', 1 => 'c'];
var_dump(array_is_list($nonSequentialNumeric)); // Output: bool(false)

By using array_is_list(), you can tell the difference between sequential and associative arrays in your PHP code, allowing for more precise array handling.

Tip: Use array_is_list() for Function Parameter Validation

When creating functions that expect a list-like array as input, you can use array_is_list() to validate the parameter:

function processListArray(array $input) {
    if (!array_is_list($input)) {
        throw new InvalidArgumentException('Input must be a list-like array');
    }
    // Process the array...
}

This helps catch potential issues early and makes your functions more robust.

Alternative Methods

Using array_keys() and range()

Another way to check if an array is a list is by comparing its keys with a range of numbers. This method uses the array_keys() and range() functions:

function is_list($arr) {
    if (empty($arr)) {
        return true;
    }
    return array_keys($arr) === range(0, count($arr) - 1);
}

This function works by:

  • Checking if the array is empty (which is a valid list).
  • Comparing the array keys with a range from 0 to the length of the array minus 1.

You can use it like this:

$sequential = ['a', 'b', 'c'];
$associative = ['x' => 1, 'y' => 2, 'z' => 3];

var_dump(is_list($sequential)); // Output: bool(true)
var_dump(is_list($associative)); // Output: bool(false)

Tip: Performance Consideration

For large arrays, this method might be less efficient than direct key checking, as it creates two new arrays (one from array_keys() and one from range()). Consider using a loop-based approach for better performance with very large datasets.

Checking Array Key Types

Another approach is to check the data type of array keys. A list-like array should only have integer keys:

function is_list_by_key_type($arr) {
    if (empty($arr)) {
        return true;
    }
    foreach ($arr as $key => $value) {
        if (!is_int($key)) {
            return false;
        }
    }
    return true;
}

This function:

  • Returns true for empty arrays.
  • Loops through the array, checking if each key is an integer.
  • Returns false if any non-integer key is found.

Here's how to use it:

$numeric_keys = [10 => 'a', 20 => 'b', 30 => 'c'];
$string_keys = ['x' => 1, 'y' => 2, 'z' => 3];

var_dump(is_list_by_key_type($numeric_keys)); // Output: bool(true)
var_dump(is_list_by_key_type($string_keys)); // Output: bool(false)

Note that this method considers arrays with non-sequential integer keys as lists, which may not always be wanted. For strict list checking, the array_keys() and range() method or the built-in array_is_list() function (PHP 8.1+) are more accurate.