PHP将所有数组视为关联数组,因此没有任何内置函数。 谁能推荐一种相当有效的方法来检查数组是否仅包含数字键?

基本上,我希望能够区分以下两者:

$sequentialArray = array('apple', 'orange', 'tomato', 'carrot');

和这个:

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

#1楼

<?phpfunction is_list($array) {return array_keys($array) === range(0, count($array) - 1);
}function is_assoc($array) {return count(array_filter(array_keys($array), 'is_string')) == count($array);
}?>

这两个得分最高的示例在$array = array('foo' => 'bar', 1)类的$array = array('foo' => 'bar', 1)无法正常工作


#2楼

我认为,如果数组的任何键不是整数(例如浮点数和空字符串”),则应将其视为关联数组。

同样,非排序整数也必须被视为关联(0,2,4,6),因为这种数组不能通过以下方式与for循环一起使用:

$n =count($arr);
for($i=0,$i<$n;$i++)

下面的函数的第二部分会检查键是否已编入索引,也适用于具有负值的键。 例如(-1,0,1,2,3,4,5)

count() = 7 , max = 5, min=-1if( 7 == (5-(-1)+1 ) // truereturn false; // array not associative/** * isAssoc Checks if an array is associative* @param $arr reference to the array to be checked* @return bool */
function IsAssoc(&$arr){$keys= array_keys($arr);foreach($keys as $key){if (!is_integer($key))return true;}// if all keys are integer then check if they are indexedif(count($arr) == (max($keys)-min($keys)+1))return false;elsereturn true;
}

#3楼

这也可以工作( 演示 ):

function array_has_numeric_keys_only(array $array)
{try {SplFixedArray::fromArray($array, true);} catch (InvalidArgumentException $e) {return false;}return true;
}

请注意,此答案的主要目的是告知您SplFixedArray的存在,而不是鼓励您将Exceptions用于此类测试。


#4楼

我认为以下两个函数是检查“数组是关联数组还是数值数组”的最佳方法。 由于“数字”可能只表示数字键或仅表示顺序数字键,因此下面列出了两个函数来检查任一条件:

function is_indexed_array(&$arr) {for (reset($arr); is_int(key($arr)); next($arr));return is_null(key($arr));
}function is_sequential_array(&$arr, $base = 0) {for (reset($arr), $base = (int) $base; key($arr) === $base++; next($arr));return is_null(key($arr));
}

第一个功能检查每个键是否为整数值。 第二个函数检查每个键是否为整数值,并另外检查所有键是否都是从$ base开始的顺序键,该值默认为0,因此如果不需要指定其他基值,可以将其省略。 如果将读指针移到数组末尾,则key($ my_array)返回null,这是for循环的结尾,如果所有键都是整数,则for循环之后的语句返回true。 如果不是,则循环会提前结束,因为键的类型为字符串,并且for循环之后的语句将返回false。 此外,后一个函数在每次比较后向$ base添加一个,以便能够检查下一个键是否具有正确的值。 严格比较使它还检查密钥是否为整数类型。 如果省略$ base或确保仅使用整数调用它,则可以忽略for循环第一部分中的$ base =(int)$ base部分。 但是由于不确定每个人,因此我将其保留。无论如何,该语句仅执行一次。 我认为这些是最有效的解决方案:

  • 明智的记忆:不复制数据或键范围。 进行一次array_values或array_keys的过程似乎更短(代码更少),但是请记住,一旦调用该函数,后台就会发生什么。 是的,比其他解决方案中的(可见)语句更多,但这不是什么要紧,是吗?
  • 时间明智:除了复制/提取数据和/或密钥还需要花费时间外,此解决方案比进行foreach效率更高。 同样,对于某些人来说,一个foreach似乎更有效,因为它的符号更短,但是在后台foreach也调用reset,key和next来进行循环。 但是此外,它还调用有效来检查结束条件,由于与整数检查结合使用,因此在此避免了这种情况。

请记住,数组键只能是整数或字符串,并且严格数字字符串(例如“ 1”(但不能为“ 01”))将转换为整数。 这使得检查整数键成为唯一需要的操作,除了计数之外,如果您希望数组是连续的。 自然,如果is_indexed_array返回false,则该数组可以视为关联数组。 我说“看过”,因为实际上它们都是。


#5楼

如《 任择议定书》所述 :

PHP将所有数组视为关联数组

编写一个检查数组是否关联的函数不是很明智(IMHO)。 首先,第一件事是 : PHP数组中的键是什么 ?:

可以是整数字符串

这意味着有3种可能的情况:

  • 情况1.所有键都是数字 / 整数
  • 情况2。所有键都是字符串
  • 情况3.一些键是字符串 ,一些键是数字 / 整数

我们可以使用以下功能检查每种情况。

情况1:所有键都是数字 / 整数

注意对于空数组,此函数也返回true

//! Check whether the input is an array whose keys are all integers.
/*!\param[in] $InputArray          (array) Input array.\return                         (bool) \b true iff the input is an array whose keys are all integers.
*/
function IsArrayAllKeyInt($InputArray)
{if(!is_array($InputArray)){return false;}if(count($InputArray) <= 0){return true;}return array_unique(array_map("is_int", array_keys($InputArray))) === array(true);
}

情况2:所有键都是字符串

注意对于空数组,此函数也返回true

//! Check whether the input is an array whose keys are all strings.
/*!\param[in] $InputArray          (array) Input array.\return                         (bool) \b true iff the input is an array whose keys are all strings.
*/
function IsArrayAllKeyString($InputArray)
{if(!is_array($InputArray)){return false;}if(count($InputArray) <= 0){return true;}return array_unique(array_map("is_string", array_keys($InputArray))) === array(true);
}

情况3.一些键是字符串 ,一些键是数字 / 整数

注意对于空数组,此函数也返回true

//! Check whether the input is an array with at least one key being an integer and at least one key being a string.
/*!\param[in] $InputArray          (array) Input array.\return                         (bool) \b true iff the input is an array with at least one key being an integer and at least one key being a string.
*/
function IsArraySomeKeyIntAndSomeKeyString($InputArray)
{if(!is_array($InputArray)){return false;}if(count($InputArray) <= 0){return true;}return count(array_unique(array_map("is_string", array_keys($InputArray)))) >= 2;
}

它遵循:

  • 如果该值不是数组 ,则所有3个函数均返回false
  • 如果值为空数组 ,则所有3个函数均返回true
    (根据定义,“ 由于空集合是任何集合A的子集,因为它的所有元素都属于A ”)。
  • 如果该值为非空数组 ,则恰好1个函数返回true

现在,让一个数组成为我们都已习惯的“真正”数组 ,这意味着:

  • 它的键全是数字 / 整数
  • 它的密钥是顺序的 (即,按步骤1增加)。
  • 其键从零开始

我们可以使用以下功能进行检查。

情况3a。 键是数字 / 整数顺序从零开始的键

注意对于空数组,此函数也返回true

//! Check whether the input is an array whose keys are numeric, sequential, and zero-based.
/*!\param[in] $InputArray          (array) Input array.\return                         (bool) \b true iff the input is an array whose keys are numeric, sequential, and zero-based.
*/
function IsArrayKeyNumericSequentialZeroBased($InputArray)
{if(!is_array($InputArray)){return false;}if(count($InputArray) <= 0){return true;}return array_keys($InputArray) === range(0, count($InputArray) - 1);
}

注意事项/陷阱(或者,甚至更多有关PHP中数组键的特殊事实)

整数键

这些数组的键是整数

array(0 => "b");
array(13 => "b");
array(-13 => "b");          // Negative integers are also integers.
array(0x1A => "b");         // Hexadecimal notation.

字符串键

这些数组的键是字符串

array("fish and chips" => "b");
array("" => "b");                                   // An empty string is also a string.
array("stackoverflow_email@example.com" => "b");    // Strings may contain non-alphanumeric characters.
array("stack\t\"over\"\r\nflow's cool" => "b");     // Strings may contain special characters.
array('$tα€k↔øv∈rflöw⛄' => "b");                    // Strings may contain all kinds of symbols.
array("functіon" => "b");                           // You think this looks fine? Think again! (see https://stackoverflow.com/q/9246051/1402846)
array("ま말轉转ДŁ" => "b");                         // How about Japanese/Korean/Chinese/Russian/Polish?
array("fi\x0sh" => "b");                            // Strings may contain null characters.
array(file_get_contents("https://www.google.com/images/nav_logo114.png") => "b");   // Strings may even be binary!

看起来像字符串的整数键

如果您认为array("13" => "b")字符串那么您错了 。 从这里的文档:

包含有效整数的字符串将转换为整数类型。 例如,键“ 8”实际上将存储在8以下。另一方面,“ 08”将不是强制转换,因为它不是有效的十进制整数。

例如,这些数组的键是整数

array("13" => "b");
array("-13" => "b");                        // Negative, ok.

但是这些数组的关键是字符串

array("13." => "b");
array("+13" => "b");                        // Positive, not ok.
array("-013" => "b");
array("0x1A" => "b");                       // Not converted to integers even though it's a valid hexadecimal number.
array("013" => "b");                        // Not converted to integers even though it's a valid octal number.
array("18446744073709551616" => "b");       // Not converted to integers as it can't fit into a 64-bit integer.

而且,根据文档 ,

整数的大小取决于平台,尽管通常的最大值约为20亿(32位带符号)。 64位平台的最大值通常约为9E18(Windows始终为32位)。 PHP不支持无符号整数。

因此,此数组的键可以是整数 ,也可以不是 整数 -这取决于您的平台。

array("60000000000" => "b");                // Array key could be integer or string, it can fit into a 64-bit (but not 32-bit) integer.

更糟的是,PHP趋向于如果整数是2 31 = 2,147,483,648边界(参见邻近错误51430 , 错误52899 )。 例如,在我的本地环境(Windows 7上XAMPP 1.7.7上的PHP 5.3.8)上, var_dump(array("2147483647" => "b"))给出

array(1) {[2147483647]=>string(1) "b"
}

但在此使用键盘的现场演示 (PHP 5.2.5)上,相同的表达式给出了

array(1) {["2147483647"]=>string(1) "b"
}

因此,即使2147483647是有效的带符号32位整数 ,密钥在一个环境中也是一个整数 ,而在另一个环境中是一个字符串


#6楼

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

下面,我介绍三种不同严格性的方法。

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

#7楼

我注意到此问题有两种流行的方法:一种使用array_values() ,另一种使用key() 。 为了找出更快的速度,我编写了一个小程序:

$arrays = Array('Array #1' => Array(1, 2, 3, 54, 23, 212, 123, 1, 1),'Array #2' => Array("Stack", 1.5, 20, Array(3.4)),'Array #3' => Array(1 => 4, 2 => 2),'Array #4' => Array(3.0, "2", 3000, "Stack", 5 => "4"),'Array #5' => Array("3" => 4, "2" => 2),'Array #6' => Array("0" => "One", 1.0 => "Two", 2 => "Three"),'Array #7' => Array(3 => "asdf", 4 => "asdf"),'Array #8' => Array("apple" => 1, "orange" => 2),
);function is_indexed_array_1(Array &$arr) {return $arr === array_values($arr);
}function is_indexed_array_2(Array &$arr) {for (reset($arr), $i = 0; key($arr) === $i++; next($arr));return is_null(key($arr));
}// Method #1
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {foreach ($arrays as $array) {$dummy = is_indexed_array_1($array);}
}
$end = microtime(true);
echo "Time taken with method #1 = ".round(($end-$start)*1000.0,3)."ms\n";// Method #2
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {foreach ($arrays as $array) {$dummy = is_indexed_array_2($array);}
}
$end = microtime(true);
echo "Time taken with method #1 = ".round(($end-$start)*1000.0,3)."ms\n";

CentOS上PHP 5.2上程序的输出如下:

方法1花费的时间= 10.745ms
方法2花费的时间= 18.239ms

PHP 5.3上的输出产生了相似的结果。 显然,使用array_values()更快。


#8楼

除非PHP具有内置功能,否则您将无法在O(n)内完成它-枚举所有键并检查整数类型。 实际上,您还想确保没有孔,因此您的算法可能如下所示:

for i in 0 to len(your_array):if not defined(your-array[i]):# this is not an array array, it's an associative array :)

但是为什么要打扰呢? 只是假设数组是您期望的类型。 如果不是这样,它只会在您的脸上炸开-对您来说,这是动态编程! 测试您的代码,一切都会很好...


#9楼

您问了两个不完全相同的问题:

  • 首先,如何确定数组是否只有数字键
  • 其次,如何确定数组是否具有从0开始的连续数字键

考虑您实际上需要哪种行为。 (这也许可以满足您的目的。)

kurO上尉很好地回答了第一个问题(只需检查所有键是否都是数字)。

对于第二个问题(检查数组是否为零索引和顺序索引),可以使用以下函数:

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

#10楼

我知道向这个庞大的队列添加答案有点没有意义,但是这是一个可读的O(n)解决方案,不需要重复任何值:

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

而不是检查键,看看他们都是数字,你迭代, 在那里为一个数值数组,并确保它们存在的关键。


#11楼

function checkAssoc($array){return  ctype_digit( implode('', array_keys($array) ) );
}

#12楼

我的解决方案:

function isAssociative(array $array)
{return array_keys(array_merge($array)) !== range(0, count($array) - 1);
}

单个数组上的array_merge将重新索引所有integer键,但不会重新索引其他integer 。 例如:

array_merge([1 => 'One', 3 => 'Three', 'two' => 'Two', 6 => 'Six']);// This will returns [0 => 'One', 1 => 'Three', 'two' => 'Two', 2 => 'Six']

因此,如果创建了一个列表(一个非关联数组) ['a', 'b', 'c']那么将删除一个未unset($a[1])的值unset($a[1])然后调用array_merge ,该列表将从以下位置重新索引0。


#13楼

从源头上又快了一个。 适合json_encode (和bson_encode )的编码。 因此也符合javascript Array规范。

function isSequential($value){if(is_array($value) || ($value instanceof \Countable && $value instanceof \ArrayAccess)){for ($i = count($value) - 1; $i >= 0; $i--) {if (!isset($value[$i]) && !array_key_exists($i, $value)) {return false;}}return true;} else {throw new \InvalidArgumentException(sprintf('Data type "%s" is not supported by method %s', gettype($value), __METHOD__));}
}

#14楼

当然,这是一个更好的选择。

<?php
$arr = array(1,2,3,4);
$isIndexed = array_values($arr) === $arr;

#15楼

通过使用xarray PHP扩展

您可以非常快地完成此操作(在PHP 5.6中快30倍以上):

if (array_is_indexed($array)) {  }

要么:

if (array_is_assoc($array)) {  }

#16楼

解决此问题的一种方法是背负json_encode ,后者已经拥有自己的内部方法,可以区分关联数组和索引数组,以便输出正确的JSON。

您可以通过检查编码后返回的第一个字符是{ (关联数组)还是[ (索引数组)来完成此操作。

// Too short :)
function is_assoc($arr) {ksort($arr);return json_encode($arr)[0] === '{';
}

#17楼

function array_is_assoc(array $a) {$i = 0;foreach ($a as $k => $v) {if ($k !== $i++) {return true;}}return false;
}

快速,简洁,高效存储。 没有昂贵的比较,函数调用或数组复制。


#18楼

已经给出了答案,但是关于性能的信息太多。 我写了这个小基准脚本,它显示了foreach方法是最快的。

免责声明:以下方法是从其他答案中复制粘贴的

<?phpfunction method_1(Array &$arr) {return $arr === array_values($arr);
}function method_2(Array &$arr) {for (reset($arr), $i = 0; key($arr) !== $i++; next($arr));return is_null(key($arr));
}function method_3(Array &$arr) {return array_keys($arr) === range(0, count($arr) - 1);
}function method_4(Array &$arr) {$idx = 0;foreach( $arr as $key => $val ){if( $key !== $idx )return FALSE;$idx++;}return TRUE;
}function benchmark(Array $methods, Array &$target){    foreach($methods as $method){$start = microtime(true);for ($i = 0; $i < 1000; $i++)$dummy = call_user_func($method, $target);$end = microtime(true);echo "Time taken with $method = ".round(($end-$start)*1000.0,3)."ms\n";}
}$targets = ['Huge array' => range(0, 30000),'Small array' => range(0, 1000),
];
$methods = ['method_1','method_2','method_3','method_4',
];
foreach($targets as $targetName => $target){echo "==== Benchmark using $targetName ====\n";benchmark($methods, $target);echo "\n";
}

结果:

==== Benchmark using Huge array ====
Time taken with method_1 = 5504.632ms
Time taken with method_2 = 4509.445ms
Time taken with method_3 = 8614.883ms
Time taken with method_4 = 2720.934ms==== Benchmark using Small array ====
Time taken with method_1 = 77.159ms
Time taken with method_2 = 130.03ms
Time taken with method_3 = 160.866ms
Time taken with method_4 = 69.946ms

#19楼

我已经使用了array_keys($obj) !== range(0, count($obj) - 1)array_values($arr) !== $arr (它们都是双精度的,尽管第二个比第一个),但对于大型数组都失败。

这是因为array_keysarray_values都是非常昂贵的操作(因为它们会构建一个新的数组,其大小大致与原始数组相同)。

与上面提供的方法相比,以下功能更强大:

function array_type( $obj ){$last_key = -1;$type = 'index';foreach( $obj as $key => $val ){if( !is_int( $key ) || $key < 0 ){return 'assoc';}if( $key !== $last_key + 1 ){$type = 'sparse';}$last_key = $key;}return $type;
}

还要注意,如果您不希望将稀疏数组与关联数组区分开,则可以简单地从两个if块中返回'assoc'

最后,尽管此页上的“优雅”看起来比许多“解决方案”要少得多,但实际上它的效率要高得多。 几乎所有关联数组都将立即被检测到。 仅索引数组将得到详尽检查,并且上面概述的方法不仅详尽检查索引数组,而且还会复制它们。


#20楼

该函数可以处理:

  • 索引中带有孔的数组(例如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;
}

#21楼

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

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

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


#22楼

已经有很多答案,但是这是Laravel在其Arr类中依赖的方法:

/*** Determines if an array is associative.** An array is "associative" if it doesn't have sequential numerical keys beginning with zero.** @param  array  $array* @return bool*/
public static function isAssoc(array $array)
{$keys = array_keys($array);return array_keys($keys) !== $keys;
}

来源: https : //github.com/laravel/framework/blob/5.4/src/Illuminate/Support/Arr.php


#23楼

经过一些本地基准测试,调试,编译器探测,性能分析,并滥用3v4l.org跨多个版本进行基准测试(是的,我警告停止),然后与我可以找到的每个变化进行比较...

我为您提供了一个有机推导的最佳平均最坏情况关联数组测试函数,该函数在最坏的情况下比所有其他平均情况都好或更好。

/*** Tests if an array is an associative array.** @param array $array An array to test.* @return boolean True if the array is associative, otherwise false.*/
function is_assoc(array &$arr) {// don't try to check non-arrays or empty arraysif (FALSE === is_array($arr) || 0 === ($l = count($arr))) {return false;}// shortcut by guessing at the beginningreset($arr);if (key($arr) !== 0) {return true;}// shortcut by guessing at the endend($arr);if (key($arr) !== $l-1) {return true;}// rely on php to optimize test by reference or fast comparereturn array_values($arr) !== $arr;
}

从https://3v4l.org/rkieX :

<?php// array_values
function method_1(Array &$arr) {return $arr === array_values($arr);
}// method_2 was DQ; did not actually work// array_keys
function method_3(Array &$arr) {return array_keys($arr) === range(0, count($arr) - 1);
}// foreach
function method_4(Array &$arr) {$idx = 0;foreach( $arr as $key => $val ){if( $key !== $idx )return FALSE;++$idx;}return TRUE;
}// guessing
function method_5(Array &$arr) {global $METHOD_5_KEY;$i = 0;$l = count($arr)-1;end($arr);if ( key($arr) !== $l )return FALSE;reset($arr);do {if ( $i !== key($arr) )return FALSE;++$i;next($arr);} while ($i < $l);return TRUE;
}// naieve
function method_6(Array &$arr) {$i = 0;$l = count($arr);do {if ( NULL === @$arr[$i] )return FALSE;++$i;} while ($i < $l);return TRUE;
}// deep reference reliance
function method_7(Array &$arr) {return array_keys(array_values($arr)) === array_keys($arr);
}// organic (guessing + array_values)
function method_8(Array &$arr) {reset($arr);if ( key($arr) !== 0 )return FALSE;end($arr);if ( key($arr) !== count($arr)-1 )return FALSE;return array_values($arr) === $arr;
}function benchmark(Array &$methods, Array &$target, $expected){    foreach($methods as $method){$start = microtime(true);for ($i = 0; $i < 2000; ++$i) {//$dummy = call_user_func($method, $target);if ( $method($target) !== $expected ) {echo "Method $method is disqualified for returning an incorrect result.\n";unset($methods[array_search($method,$methods,true)]);$i = 0;break;}}if ( $i != 0 ) {$end = microtime(true);echo "Time taken with $method = ".round(($end-$start)*1000.0,3)."ms\n";}}
}$true_targets = ['Giant array' => range(0, 500),'Tiny array' => range(0, 20),
];$g = range(0,10);
unset($g[0]);$false_targets = ['Large array 1' => range(0, 100) + ['a'=>'a'] + range(101, 200),'Large array 2' => ['a'=>'a'] + range(0, 200),'Tiny array' => range(0, 10) + ['a'=>'a'] + range(11, 20),'Gotcha array' => $g,
];$methods = ['method_1','method_3','method_4','method_5','method_6','method_7','method_8'
];foreach($false_targets as $targetName => $target){echo "==== Benchmark using $targetName expecing FALSE ====\n";benchmark($methods, $target, false);echo "\n";
}
foreach($true_targets as $targetName => $target){echo "==== Benchmark using $targetName expecting TRUE ====\n";benchmark($methods, $target, true);echo "\n";
}

#24楼

这可以解决吗?

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

需要说明的是,显然数组指针已被重置,但我想可能在遍历或使用数组之前就使用了该函数。


#25楼

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

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

#26楼

这个问题的许多评论者不了解数组在PHP中的工作方式。 从数组文档中 :

键可以是整数或字符串。 如果键是整数的标准表示,它将被解释为整数(即​​“ 8”将被解释为8,而“ 08”将被解释为“ 08”)。 键中的浮点数将被截断为整数。 索引数组和关联数组类型与PHP中的类型相同,都可以包含整数索引和字符串索引。

换句话说,没有像“ 8”这样的数组键,因为它将始终(无声地)转换为整数8。因此,不必在整数和数字字符串之间进行区分。

如果您想以最有效的方式检查数组中的非整数键,而又不复制数组的一部分(例如array_keys()进行复制)或全部复制(例如foreach进行复制),请执行以下操作:

function keyedNext( &$arr, &$k){$k = key($arr);return next($arr);
}for ($k = key(reset($my_array)); is_int($k); keyedNext($my_array,$k))$onlyIntKeys = is_null($k);

之所以可行,是因为当当前数组位置无效时,key()返回NULL,并且NULL永远不可能是有效的键(如果尝试将NULL用作数组键,则它会静默转换为“”)。


#27楼

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

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

之所以有效,是因为它将键(对于连续数组,其始终为0,1,2等)与键(其始终为0,1,2等)的键进行比较。


#28楼

这是我使用的方法:

function is_associative ( $a )
{return in_array(false, array_map('is_numeric', array_keys($a)));
}assert( true === is_associative(array(1, 2, 3, 4)) );assert( false === is_associative(array('foo' => 'bar', 'bar' => 'baz')) );assert( false === is_associative(array(1, 2, 3, 'foo' => 'bar')) );

请注意,这不考虑特殊情况,例如:

$a = array( 1, 2, 3, 4 );unset($a[1]);assert( true === is_associative($a) );

抱歉,不能帮您。 它对于适当大小的数组也有一定的性能,因为它不会产生不必要的副本。 正是这些小事情使Python和Ruby变得更加好用...:P


#29楼

速度方面:

function isAssoc($array)
{return ($array !== array_values($array));
}

内存方面:

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

#30楼

我比较了数组的键和数组的array_values()结果的键之间的差异,该数组将始终是具有整数索引的数组。 如果键相同,则它不是关联数组。

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

如何检查PHP数组是关联数组还是顺序数组?相关推荐

  1. Linux shell 中的数组和关联数组

    写在前面的话 我用开始废柴了,这个又是写给我自己看的了. 普通数组 1.数组的定义 在Linux shell中定义一个普通的数组很简单,首先我们先给数组命名(当然要符合所有的命名规则咯).定义数组的一 ...

  2. php索引数组转键数组,php索引数组和关联数组

    这篇文章主要介绍的内容是关于php索引数组和关联数组,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 最近遇到个bug,记录一下//定义一个数组 $arr = Array('a','b' ...

  3. Linux脚本关联,shell数组和关联数组

    数组和关联数组 Bash 支持普通数组和关联数组,前者使用整数作为数组索引,后者使用字符串作为数组索引. Bash 从4.0版本开始才支持关联数组 1 数组 1.1 在单行中使用数值列表来定义一个数组 ...

  4. Linux之数组和关联数组

    数组是shell脚本非常重要的组成部分,它借助索引将多个独立的数据存储为一个集合.普通 数组只能使用整数作为数组索引.Bash也支持关联数组,它可以使用字符串作为数组索引.在很 多情况下,采用字符串式 ...

  5. php判断是否是关联数组,php 关联数组判断是否为空

    先看一个关联数组判断为空的代码,然后我们详细讲讲关于数据空的处理. $array = array(0); if(empty($array)){ echo "我空了 "; }else ...

  6. linux 关联数组,Linux shell数组与关联数组的用法实例

    Linux shell数组与关联数组的用法实例 1. 关联数组 使用 declare -A(declare 的用法请使用 help 进行查看,help declare) 进行声明关联数组变量: $ d ...

  7. 索引数组与关联数组的定义及区别

    索引数组 用数字作为键名的数组一般叫做索引数组 用字符串表示键的数组就是下面要介绍的关联数组. 索引数组的键是整数,而且从0开始以此类推. 例如: a=array('山东省','济南市','莱芜区') ...

  8. php 数字数组和关联数组,PHP数组、数字数组、关联数组和多维数组

    数组是一种数据结构,将一个或多个类似的值存储在一个单一的值. 有三种不同类型的数组,每个数组值是使用一个ID访问c被称为数组索引. 数字数组,数组和一个数字索引.以线性方式值存储和访问 关联数组,数组 ...

  9. php array 关联数组,php关联数组的输出

    php 动态关联数组,PHP 反射API,php遍历关联数组,php关联数组的输出 php数组学习数组索引数组关联数组_互联网_IT/计算机_专业资料.php数组 php array php索引数组 ...

最新文章

  1. ACM SIGKDD | MoFlow:基于流的分子图生成模型
  2. Spring.ImportSelector接口
  3. python蟒蛇绘制 C
  4. c语言将一个已知头结点的单链表逆序_C语言实现常用数据结构:静态链表数组实现(第5篇)...
  5. python网络编程3-socketserver模块
  6. When we use PdfStamper to merge fields.
  7. Lesson 29 SVD decomposition
  8. python如何运行一个python程序_python如何运行?第一个python小程序示范
  9. SOA与微服务的比较和对比
  10. 建立桌面文件管理格子_win10桌面分区,win10如何创建桌面格子
  11. 基础线性代数知识点总结与回顾(三):向量空间和二次型
  12. java 文件流 乱码_Java IO流之中文乱码
  13. 微铺子点单系统具体介绍 - 争做国内最专业的微信商店平台,微信外卖订餐系统!...
  14. windows禅道环境搭建
  15. Java实现微信公众号每日推送
  16. 5-20 打印九九口诀表 (15分)
  17. C语言 多种方法求最大公因数和最小公倍数
  18. 百度地图API入门1-申请百度API key
  19. Java web学习——Spring MVC项目实例,三层架构通过JDBC链接SQLServer2012
  20. 互联网生活有三大定律,摩尔定律、梅特卡夫定律和颠覆定律。

热门文章

  1. nginx+php5-fpm安装
  2. angularjs应用总结
  3. SPOJ QTree【树链剖分】
  4. LA4794 Sharing Chocolate
  5. js 的函数参数的默认值问题
  6. 监测 Linux 上失败的登录尝试方法分享
  7. HP服务器集成 iLO 端口的配置
  8. 阿里云centos7监控postgres9.6.6
  9. zabbix监控硬盘
  10. 关于数据准备时,自动棌番的主键,这一字段数据的注意(IT总结之五)