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

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

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

这:

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

当前回答

这个问题中的许多评论者不理解PHP中的数组是如何工作的。从数组文档:

键可以是整数,也可以是字符串。如果一个键是一个整数的标准表示,它将被这样解释(即。“8”解释为8,“08”解释为“08”)。key中的浮点数被截断为整数。在PHP中,索引数组和关联数组类型是相同的类型,它们都可以包含整数和字符串索引。

换句话说,没有数组键“8”这样的东西,因为它总是(无声地)转换为整数8。因此,试图区分整数和数字字符串是不必要的。

如果你想要最有效的方法来检查一个数组的非整数键,而不需要复制数组的一部分(像array_keys()那样)或全部(像foreach那样):

function keyedNext( &$arr, &$k){
    $k = key($arr);
    return next($arr);
}

for ($k = key(reset($my_array)); is_int($k); keyedNext($my_array,$k))
    $onlyIntKeys = is_null($k);

这是因为key()在当前数组位置无效时返回NULL,并且NULL永远不会是一个有效的键(如果你试图使用NULL作为数组键,它会被无声地转换为“”)。

其他回答

速度明智:

function isAssoc($array)
{
    return ($array !== array_values($array));
}

Memory-wise:

function isAssoc($array)
{
    $array = array_keys($array); return ($array !== array_keys($array));
}
function isAssoc($arr)
{
    $a = array_keys($arr);
    for($i = 0, $t = count($a); $i < $t; $i++)
    {
        if($a[$i] != $i)
        {
            return false;
        }
    }
    return true;
}

我很惊讶没有人提到array_key_first()

对于您的测试用例:

$sequentialArray = array('apple', 'orange', 'tomato', 'carrot');
$isIndexedArray = is_int( array_key_first($sequentialArray) ); // true

$assocArray = array('fruit1' => 'apple', 
                'fruit2' => 'orange', 
                'veg1' => 'tomato', 
                'veg2' => 'carrot');

$isIndexedArray = is_int( array_key_first($assocArray) ); // false

在这里阅读更多关于这个函数的信息。

这是解决方案吗?

  public static function isArrayAssociative(array $array) {
      reset($array);
      return !is_int(key($array));
  }

需要注意的是,数组光标被重置了,但我想说的是,这个函数可能在数组被遍历或使用之前就被使用了。

对于使用Laravel的用户:

如果给定数组是关联数组,则isAssoc返回true。如果数组没有以0开头的连续数字键,则数组被认为是“关联的”:

use Illuminate\Support\Arr;

$isAssoc = Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]);

// true

$isAssoc = Arr::isAssoc([1, 2, 3]);

// false

https://laravel.com/docs/8.x/helpers#method-array-isassoc