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

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

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

这:

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

当前回答

这是解决方案吗?

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

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

其他回答

这个问题实际上在php数组中是没有用的,因为php的本质是数组不应该是完全关联的或索引的,它可以是两者的组合,用户定义和赋值数组的方式可以是两者的组合。参见下面的示例

$y= array(5);
$y["0x"]="n";
$y["vbg"]="12132";
$y[1] = "k";

var_dump($y); //this will output 4 element array

echo "</br>" .$y["0x"]."</br>".$y[0];

for($x=0;$x<sizeof($y);$x++){ // this will output all index elements & gives error after that
    echo "</br> index elements ".$y[$x];
}

正确的问题是,数组中的所有元素都是关联的还是下标的。如果你真的知道它只能是关联数组或索引数组而不是两者的组合,你可以简单地使用这个方法来确定它是索引数组还是关联数组。

function AssocTest(&$arr){
    if(is_array($arr)){

        reset($arr); // reset pointer to first element of array

        if(gettype(key($arr)) == "string"){ //get the type(nature) of first element key 
            return true;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

你可以正常使用它

echo(AssocTest($y)?  "Associative array": "Not an Associative array/ Not an array at all");

重要的是,evan,你已经初始化了一个关联数组但是你给关联数组的名字只是数字当它被PHP读取时它会被当作一个索引数组如果你没有显式地给字符串名字。看看下面的例子。

$y["0"]="n";
$y["1"]="12132";
$y["22"] = "k";

//both will get the same output
echo "<br/> s0 ".$y["22"];
echo "<br/> s0 ".$y[22];

for($x=0;$x<count($y);$x++){
   echo "<br/> arr ".$y[$x]; // this will output up to 2nd element and give an error after

}

如果你需要确保数组中的所有元素都被精确索引,或者是关联的,没有其他方法,只能对所有元素赋真,并检查每个元素键通过生成索引数组,就像这里很多人发布的那样。

function fullAssocTest(&$arr)
{
    if(is_array($arr)){
        return (array_keys($arr) !== range(0, count($arr) - 1));
    }
}

它的代码更少,但这个东西真的是过程密集和真正不必要的工作。

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

<?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
?>

仅仅检查数组是否有非整数键(而不是数组是否按顺序索引或零索引):

function has_string_keys(array $array) {
  return count(array_filter(array_keys($array), 'is_string')) > 0;
}

如果至少有一个字符串键,$array将被视为一个关联数组。

检查数组是否有所有的关联键。使用stdClass & get_object_vars ^):

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

$assoc_object = (object) $assocArray;
$isAssoc = (count($assocArray) === count (get_object_vars($assoc_object)));  
var_dump($isAssoc); // true

为什么?函数get_object_vars只返回可访问的属性(请参阅在将数组转换为对象期间发生的更多信息)。然后,只是逻辑上:如果基本数组元素的计数等于对象的可访问属性的计数-所有键都是关联的。

一些测试:

$assocArray = array('apple', 'orange', 'tomato', 'carrot');
$assoc_object = (object) $assocArray; 
$isAssoc = (count($assocArray) === count (get_object_vars($assoc_object)));
var_dump($isAssoc); // false 
//...

$assocArray = array( 0 => 'apple', 'orange', 'tomato', '4' => 'carrot');
$assoc_object = (object) $assocArray; 
$isAssoc = (count($assocArray) === count (get_object_vars($assoc_object)));
var_dump($isAssoc); // false 

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

$assoc_object = (object) $assocArray;
$isAssoc = (count($assocArray) === count (get_object_vars($assoc_object)));  
var_dump($isAssoc); //false

Etc.

这个函数可以处理:

索引有孔的数组(例如1、2、4、5、8、10) 带有“0x”键的数组:例如,键“08”是关联的,键“8”是顺序的。

思想很简单:如果其中一个键不是整数,它就是关联数组,否则就是顺序数组。

function is_asso($a){
    foreach(array_keys($a) as $key) {if (!is_int($key)) return TRUE;}
    return FALSE;
}