PHP将所有数组都视为关联数组,因此没有任何内置函数。谁能推荐一种相当有效的方法来检查数组是否“是一个列表”(只包含从0开始的数字键)?

基本上,我希望能够区分这些:

$sequentialArray = [
    'apple', 'orange', 'tomato', 'carrot'
];

这:

$assocArray = [
    'fruit1' => 'apple',
    'fruit2' => 'orange',
    'veg1' => 'tomato',
    'veg2' => 'carrot'
];

当前回答

只是补充我的意见,我认为它应该是相当有效的基于@nonsensei的基准,以及清晰易读:

function is_associative(array $array): bool
{
    foreach ($array as $key => $value)
    {
        if (!is_string($key)) return false;
    }
    return true;
}

其他回答

几天前我又遇到了这个问题,我想利用array_merge特殊属性:

如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。但是,如果数组包含数字键,则后一个值不会覆盖原始值,而是被追加。输入数组中具有数字键的值将使用结果数组中从0开始的递增键重新编号。 所以为什么不使用:

function Is_Indexed_Arr($arr){
    $arr_copy = $arr;
    if((2*count($arr)) == count(array_merge($arr, $arr_copy))){
        return 1;
    }
    return 0;
}

这也会工作(演示):

function array_has_numeric_keys_only(array $array)
{
    try {
        SplFixedArray::fromArray($array, true);
    } catch (InvalidArgumentException $e) {
        return false;
    }
    return true;
}

请注意,这个答案的主要观点是告诉你SplFixedArray的存在,而不是鼓励你对这些类型的测试使用异常。

function is_array_assoc($foo) {
    if (is_array($foo)) {
        return (count(array_filter(array_keys($foo), 'is_string')) > 0);
    }
    return false;
}

还有另一种方法。

function array_isassociative($array)
{
    // Create new Array,  Make it the same size as the input array
    $compareArray = array_pad(array(), count($array), 0);

    // Compare the two array_keys
    return (count(array_diff_key($array, $compareArray))) ? true : false;

}
function is_associative($arr) {
  return (array_merge($arr) !== $arr || count(array_filter($arr, 'is_string', ARRAY_FILTER_USE_KEY)) > 0);
}