如何确定可能关联数组中的第一个键?我的第一个想法是遍历整个数组,然后立即中断,代码如下:
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)
reset()
也恰好会返回任何数组的第一个元素(值,而不是键),这也很方便。 - devios1reset()
的注释,它说“不要使用reset()
来获取关联数组的第一个值。对于真正的数组来说它很好用,但是在迭代器对象上会出现意想不到的结果。http://bugs.php.net/bug.php?id=38478”。这是否仍然正确?我感到困惑。 - Dmitry Pashkevichexit;
或忘记关闭它们打开的东西等等。 - Pacerierarray_keys
返回一个包含所有键名的数组。获取第一个条目。或者,您可以在数组上调用reset
,然后使用key
。后一种方法可能略微快一些(虽然我没有测试过),但它会重置内部指针。
foreach
+ break
和 reset
+ key
并没有性能上的区别。但是前者看起来相当奇怪,所以基于风格方面考虑,我更喜欢使用后者。 - troelsknforeach
不会为它创建内部副本,而只是迭代一个指针,类似于使用更低级别的 next
、current
等。 - troelskn有趣的是,使用foreach循环实际上是做这件事情最有效的方法。
既然原帖子特别询问了效率问题,应该指出当前所有答案实际上都比foreach要慢得多。
我在php 5.4上进行了基准测试,发现重置/键指针方法(被采纳的答案)大约比foreach慢7倍。其他操作整个数组的方法(array_keys,array_flip)显然比这更慢,并且在处理大型数组时会变得更糟。
Foreach根本不低效,请放心使用它!
编辑于2015-03-03:
已请求基准测试脚本,我没有原始文件,但代替做了一些新的测试。这次我发现foreach只比重置/键快两倍左右。我使用了一个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
遍历 http://3v4l.org/gRoGD/perf#tabs
foreach
循环不会复制数组,除非你在 foreach 循环内直接修改它。在 PHP5 中,在某些情况下(当其 refcount > 1 时)可能会复制数组结构,你实际上是正确的,这可能会对性能产生重大影响。幸运的是,在 PHP7 上,这个问题已经得到解决,所以不用担心了。这里有一个很好的阅读材料,介绍了现在和过去 foreach 的工作原理。 - Webmutkey($an_array)
将会给你第一个键。
根据Blixt的修改:在调用key($an_array)
之前,应该调用reset($array);
以将指针重置为数组的开头。
你可以尝试一下
array_keys($data)[0]
从2018年开始
自PHP 7.3起,有一个array_key_first()
函数可以完全实现这一功能:
$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
$firstKey = array_key_first($array); // 'foo'
文档可在此处获取。
array_keys($yourArray)[0]
。
示例:# 1
$arr = ["my" => "test", "is" => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "my"
# 2
$arr = ["test", "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "0"
# 3
$arr = [1 => "test", 2 => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "1"
解决方案的优势:
list($firstKey) = array_keys($yourArray);
你可以将array_keys($arr)[0]
作为函数参数传递(例如:doSomething(array_keys($arr)[0], $otherParameter)
)。
希望对你有所帮助
array_keys($arr)[0]
语法是否有效? - trantelist($firstKey) = array_keys($yourArray);
请查看以下内容:
$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys = array_keys($yourArray);
echo "Key = ".$keys[0];
$myArray = array(
2 => '3th element',
4 => 'first element',
1 => 'second element',
3 => '4th element'
);
echo min(array_keys($myArray)); // return 1
max()
不会返回关联数组的第一个键。max()
返回列表或数组项的最大值。 - Hamidreza
each($arr)['key']
或each($arr)[0]
都可以。 - Pacerier0.0107
, foreach:0.0217
- SeanJA