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;
}

其他回答

实际上,最有效的方法是:

function is_assoc($array){
   $keys = array_keys($array);
   return $keys !== array_keys($keys);
}

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

Laravel使用这种方法。


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);

一种廉价而肮脏的方法是这样检查:

isset($myArray[count($myArray) - 1])

...如果你的数组是这样的,你可能会得到一个假阳性:

$myArray = array("1" => "apple", "b" => "banana");

一个更彻底的方法可能是检查钥匙:

function arrayIsAssociative($myArray) {
    foreach (array_keys($myArray) as $ind => $key) {
        if (!is_numeric($key) || (isset($myArray[$ind + 1]) && $myArray[$ind + 1] != $key + 1)) {
            return true;
        }
    }
    return false;
}
// this will only return true if all the keys are numeric AND sequential, which
// is what you get when you define an array like this:
// array("a", "b", "c", "d", "e");

or

function arrayIsAssociative($myArray) {
    $l = count($myArray);
    for ($i = 0; $i < $l, ++$i) {
        if (!isset($myArray[$i])) return true;
    }
    return false;
}
// this will return a false positive on an array like this:
$x = array(1 => "b", 0 => "a", 2 => "c", 4 => "e", 3 => "d");

修改最流行的答案。 这需要更多的处理,但更准确。

<?php
//$a is a subset of $b
function isSubset($a, $b)
{
    foreach($a =>$v)
        if(array_search($v, $b) === false)
            return false;

    return true;

    //less effecient, clearer implementation. (uses === for comparison)
    //return array_intersect($a, $b) === $a;
}

function isAssoc($arr)
{
    return !isSubset(array_keys($arr), range(0, count($arr) - 1));
}

var_dump(isAssoc(array('a', 'b', 'c'))); // false
var_dump(isAssoc(array(1 => 'a', 0 => 'b', 2 => 'c'))); // false
var_dump(isAssoc(array("0" => 'a', "1" => 'b', "2" => 'c'))); // false 
//(use === in isSubset to get 'true' for above statement)
var_dump(isAssoc(array("a" => 'a', "b" => 'b', "c" => 'c'))); // true
?>

我比较数组的键值和数组的array_values()结果的键值之间的差异,数组始终是一个具有整数下标的数组。如果键是相同的,它就不是一个关联数组。

function isHash($array) {
    if (!is_array($array)) return false;
    $diff = array_diff_assoc($array, array_values($array));
    return (empty($diff)) ? false : true;
}