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

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

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

这:

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

当前回答

检测关联数组(哈希数组)的最佳函数

<?php
function is_assoc($arr) { return (array_values($arr) !== $arr); }
?>

其他回答

我认为标量数组的定义因应用程序而异。也就是说,一些应用程序将需要更严格的定义标量数组,而一些应用程序将需要更宽松的定义。

下面我将介绍3种不同严格程度的方法。

<?php
/**
 * Since PHP stores all arrays as associative internally, there is no proper
 * definition of a scalar array.
 * 
 * As such, developers are likely to have varying definitions of scalar array,
 * based on their application needs.
 * 
 * In this file, I present 3 increasingly strict methods of determining if an
 * array is scalar.
 * 
 * @author David Farrell <DavidPFarrell@gmail.com>
 */

/**
 * isArrayWithOnlyIntKeys defines a scalar array as containing
 * only integer keys.
 * 
 * If you are explicitly setting integer keys on an array, you
 * may need this function to determine scalar-ness.
 * 
 * @param array $a
 * @return boolean
 */ 
function isArrayWithOnlyIntKeys(array $a)
{
    if (!is_array($a))
        return false;
    foreach ($a as $k => $v)
        if (!is_int($k))
            return false;
    return true;
}

/**
 * isArrayWithOnlyAscendingIntKeys defines a scalar array as
 * containing only integer keys in ascending (but not necessarily
 * sequential) order.
 * 
 * If you are performing pushes, pops, and unsets on your array,
 * you may need this function to determine scalar-ness.
 * 
 * @param array $a
 * @return boolean
 */ 
function isArrayWithOnlyAscendingIntKeys(array $a)
{
    if (!is_array($a))
        return false;
    $prev = null;
    foreach ($a as $k => $v)
    {
        if (!is_int($k) || (null !== $prev && $k <= $prev))
            return false;
        $prev = $k;
    }
    return true;
}

/**
 * isArrayWithOnlyZeroBasedSequentialIntKeys defines a scalar array
 * as containing only integer keys in sequential, ascending order,
 * starting from 0.
 * 
 * If you are only performing operations on your array that are
 * guaranteed to either maintain consistent key values, or that
 * re-base the keys for consistency, then you can use this function.
 * 
 * @param array $a
 * @return boolean
 */
function isArrayWithOnlyZeroBasedSequentialIntKeys(array $a)
{
    if (!is_array($a))
        return false;
    $i = 0;
    foreach ($a as $k => $v)
        if ($i++ !== $k)
            return false;
    return true;
}
function is_associative($arr) {
  return (array_merge($arr) !== $arr || count(array_filter($arr, 'is_string', ARRAY_FILTER_USE_KEY)) > 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;
}

我的解决方案是获得如下数组的键,并检查是否键不是整数:

private function is_hash($array) {
    foreach($array as $key => $value) {
        return ! is_int($key);
    }
    return false;
}

像下面这样获取哈希数组的array_keys是错误的:

array_keys(array(
       "abc" => "gfb",
       "bdc" => "dbc"
       )
);

将输出:

array(
       0 => "abc",
       1 => "bdc"
)

因此,将它与评分最高的答案中提到的一系列数字进行比较并不是一个好主意。它总是说它是一个哈希数组如果你试着比较键和范围。