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

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

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

这:

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

当前回答


function is_assoc(array $array): bool
{
    foreach ($array as $iValue) {
        if (is_array($iValue)) {
            return  true;
        }
    }
    return false;

}

$d= is_assoc(["id",2,3]);

var_dump($d);

其他回答

有时你可以只检查第一个数组的Key是否为0。

$isSequential = array_keys($arr)[0] ===

,或更快,但更冗长的版本:

重置(arr);$isSequential = key($arr) === 0

我只是使用key()函数。观察:

<?php
var_dump(key(array('hello'=>'world', 'hello'=>'world'))); //string(5) "hello"
var_dump(key(array('world', 'world')));                  //int(0)
var_dump(key(array("0" => 'a', "1" => 'b', "2" => 'c'))); //int(0) who makes string sequetial keys anyway????
?>

因此,仅通过检查false,就可以确定数组是否是关联的。

我知道在这个庞大的队列中添加答案有点毫无意义,但这里有一个可读的O(n)解决方案,不需要复制任何值:

function isNumericArray($array) {
    $count = count($array);
    for ($i = 0; $i < $count; $i++) {
        if (!isset($array[$i])) {
            return FALSE;
        }
    }
    return TRUE;
}

不是检查键是否都是数字,而是遍历数字数组的键并确保它们存在。

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

下面我将介绍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_assoc($array){
   $keys = array_keys($array);
   return $keys !== array_keys($keys);
}

这是因为它将键(对于顺序数组来说总是0,1,2等)与键的键(总是0,1,2等)进行比较。

Laravel使用这种方法。