在可能的关联数组中确定第一个键的最佳方法是什么?我首先想到的是,它只存储数组然后立即破坏它,如下所示:
foreach ($an_array as $key => $val) break;
因此,让 $ key 包含第一个键,但这似乎效率很低。有谁有更好的解决方案?
从PHP 7.3开始,有一个名为array_key_first()
的新内置函数,该函数将从给定数组中检索第一个键,而无需重置内部指针。查看文档以获取更多信息。
reset($array);
$first_key = key($array);
它本质上与您的初始代码相同,但是开销更少,并且正在发生的事情更加明显。
只要记住要调用reset
,否则您可能会得到数组中的任何键。您也可以使用end
而不是reset
来获取最后一个密钥。
如果您希望键获取第一个值,则reset
实际上会返回它:
$first_value = reset($array);
不过,有一种特殊情况需要提防(因此请先检查数组的长度):
$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)
array_keys
返回一个键数组。以第一个条目。另外,您可以在阵列上调用reset
,然后再调用key
。后一种方法可能会稍快一些(我没有测试过),但是它具有重置内部指针的副作用。
有趣的是,foreach 循环实际上是最有效的方法。
由于 OP 专门询问了效率,因此应该指出的是,实际上,所有当前答案的效率都比 foreach 低得多。
我使用 php 5.4 进行了基准测试,并且 reset / key 指针方法(可接受的答案)似乎比 foreach 慢 7 倍。操纵整个阵列的其他方法(array_keys,array_flip)明显更慢比并配有大型阵列工作时变得更糟 。
Foreach 一点也不低效,请随时使用它!
编辑 2015-03-03:
基准脚本已被要求,我没有原始脚本,但是做了一些新的测试。这次,我发现 foreach 仅是 reset / key 的两倍。我使用了 100 个键的数组,并且每种方法都运行了 100 万次,以得到一些明显的不同,这是简单基准测试的代码:
$array = [];
for($i=0; $i < 100; $i++)
$array["key$i"] = $i;
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
foreach ($array as $firstKey => $firstValue) {
break;
}
}
echo "foreach to get first key and value: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
$firstValue = reset($array);
$firstKey = key($array);
}
echo "reset+key to get first key and value: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
reset($array);
$firstKey = key($array);
}
echo "reset+key to get first key: " . (microtime(true) - $start) . " seconds <br />";
for($i=0, $start = microtime(true); $i < 1000000; $i++) {
$firstKey = array_keys($array)[0];
}
echo "array_keys to get first key: " . (microtime(true) - $start) . " seconds <br />";
在我的 PHP 5.5 上,输出:
foreach to get first key and value: 0.15501809120178 seconds
reset+key to get first key and value: 0.29375791549683 seconds
reset+key to get first key: 0.26421809196472 seconds
array_keys to get first key: 10.059751987457 seconds
重置 + 键http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs