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

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

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

这:

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

当前回答

Mark Amery的改进

function isAssoc($arr)
{
    // Is it set, is an array, not empty and keys are not sequentialy numeric from 0
    return isset($arr) && is_array($arr) && count($arr)!=0 && array_keys($arr) !== range(0, count($arr) - 1);
}

这个测试变量是否存在,是否为数组,是否为空数组,以及键是否从0开始连续。

来查看数组是否是关联的

if (isAssoc($array)) ...

看看它是不是数值

if (!isAssoc($array)) ...

其他回答

当然,这是一个更好的选择。

<?php
$arr = array(1,2,3,4);
$isIndexed = array_values($arr) === $arr;

这是解决方案吗?

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

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

你问了两个不完全等价的问题:

首先,如何确定数组是否只有数字键 其次,如何确定数组是否具有从0开始的连续数字键

考虑一下哪些行为是你真正需要的。(也许对你来说,这两种方法都可以。)

第一个问题(简单地检查所有键是否都是数字)由kurO船长回答得很好。

对于第二个问题(检查数组是否为0索引和顺序),您可以使用以下函数:

function isAssoc(array $arr)
{
    if (array() === $arr) return false;
    return array_keys($arr) !== range(0, count($arr) - 1);
}

var_dump(isAssoc(['a', 'b', 'c'])); // false
var_dump(isAssoc(["0" => 'a', "1" => 'b', "2" => 'c'])); // false
var_dump(isAssoc(["1" => 'a', "0" => 'b', "2" => 'c'])); // true
var_dump(isAssoc(["a" => 'a', "b" => 'b', "c" => 'c'])); // true
function array_is_assoc(array $a) {
    $i = 0;
    foreach ($a as $k => $v) {
        if ($k !== $i++) {
            return true;
        }
    }
    return false;
}

快速、简洁、高效记忆。没有昂贵的比较、函数调用或数组复制。

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