PHP将所有数组都视为关联数组,因此没有任何内置函数。谁能推荐一种相当有效的方法来检查数组是否“是一个列表”(只包含从0开始的数字键)?
基本上,我希望能够区分这些:
$sequentialArray = [
'apple', 'orange', 'tomato', 'carrot'
];
这:
$assocArray = [
'fruit1' => 'apple',
'fruit2' => 'orange',
'veg1' => 'tomato',
'veg2' => 'carrot'
];
检查数组是否有所有的关联键。使用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.
修改最流行的答案。
这需要更多的处理,但更准确。
<?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
?>
你问了两个不完全等价的问题:
首先,如何确定数组是否只有数字键
其次,如何确定数组是否具有从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