获取(可能)关联数组中的第一个键?

Get first key in a (possibly) associative array?

提问人:Alex S 提问时间:6/23/2009 最后编辑:BlixtAlex S 更新时间:1/29/2022 访问量:651917

问:

确定可能关联数组中的第一个键的最佳方法是什么?我的第一个想法是只考虑数组,然后立即破坏它,如下所示:

foreach ($an_array as $key => $val) break;

因此,$key包含第一个密钥,但这似乎效率低下。有没有人有更好的解决方案?

PHP 数组

评论

4赞 Emilio Gort 3/18/2014
为什么效率低下?
2赞 Danijel 11/1/2014
与所有答案相比,foreach 仍然是最快的 FIDDLE,PHP 5.3,我在 PHP 5.5 上的 localhost 测试表明差异略微有利于 foreach。
3赞 Pacerier 2/17/2015
@Danijel,在语义上是错误的。foreach
2赞 Pacerier 2/17/2015
@AlexS,要么 each($arr)['key'] 要么就可以了。each($arr)[0]
1赞 SeanJA 7/31/2015
@Danijel 不再是...键: , foreach:0.01070.0217

答:

86赞 troelskn 6/23/2009 #1

array_keys返回键数组。以第一个条目为例。或者,您可以调用数组,然后调用 .后一种方法可能稍微快一些(我没有测试过),但它有重置内部指针的副作用。resetkey

评论

54赞 Blixt 9/4/2009
对于未来的读者来说,只是一个(迟到的)说明:后一种方法不仅仅是“稍微”快一点。迭代整个数组、将每个键存储在另一个新创建的数组中,以及以字符串形式请求数组的第一个键之间有很大的区别。
3赞 Emilio Gort 3/18/2014
为什么与所有这些答案相比,问题中的运算效率低下?
6赞 troelskn 3/18/2014
@EmilioGort 问得好。实际上,我认为 + 和 + 的性能没有任何区别。但前者看起来很奇怪,所以对于风格问题,我更喜欢后者。foreachbreakresetkey
0赞 donquixote 3/27/2014
@EmilioGort:Afaik,foreach() 在内部复制数组。因此,我们可以假设它更慢。(如果有人能证实这一点就好了)
4赞 troelskn 3/27/2014
@donquixote我不确定,但假设它是一个常规数组(而不是实现某种或迭代器接口的对象),我相当确定不会为它创建内部副本,而只是迭代一个指针,类似于使用更低级的,等等。foreachnextcurrent
39赞 jimyi 6/23/2009 #2

key($an_array)会给你第一把钥匙

edit per Blixt:您应该调用 before 以重置指向数组开头的指针。reset($array);key($an_array)

评论

7赞 Blixt 6/23/2009
请记住,数组的指针可能不在第一个元素处,请参阅我的答案。
0赞 groovenectar 9/10/2014
我认为这个答案将在不重置的情况下帮助我的情况,因为我首先要确保数组只有一个元素。谢谢
1426赞 Blixt 6/23/2009 #3

2019年更新

PHP 7.3 开始,有一个新的内置函数,它将从给定的数组中检索第一个键,而无需重置内部指针。有关详细信息,请查看文档array_key_first()


您可以使用 resetkey

reset($array);
$first_key = key($array);

它基本上与初始代码相同,但开销少一点,并且更明显地说明了正在发生的事情。

只要记得调用 ,否则你可能会得到数组中的任何键。您也可以使用 end 而不是 of 来获取最后一个密钥。resetreset

如果您希望密钥获取第一个值,请实际返回它:reset

$first_value = reset($array);

不过,有一个特殊情况需要注意(因此请先检查数组的长度):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)

评论

150赞 devios1 8/22/2012
顺便说一句,也恰好返回任何数组的第一个元素(值,而不是键),这也很方便。reset()
6赞 Dmitry Pashkevich 1/23/2013
文档中有一条注释说 reset()' 以获取关联数组的第一个值。它适用于真正的数组,但对 Iterator 对象却出乎意料地有效。bugs.php.net/bug.php?id=38478'这还是真的吗?我很困惑reset()Don't use
15赞 Blixt 1/24/2013
@DmitryPashkevich:不要担心那个评论。他们谈论的不是对象,而是自定义对象(不是实际的数组)。我猜他们混淆了数据结构的差异,但基本上,返回第一个“键”的值,对于对象来说,它将在“错误”报告中给出的示例中,但对于数组来说,第一个键。所以不用担心,只要你使用真正的数组(创建于 ),你就不会有问题。arrayreset$proparray(…)
2赞 donquixote 3/27/2014
值得一提的是,end() 和 reset() 有副作用。但是,世界上大多数代码都不依赖于位于任何地方的内部指针,因此这通常不是问题。
1赞 Blixt 12/31/2014
@user3019105 每个数组只有一个内部指针,这意味着如果函数外部的任何代码更改了它(通过调用 、 或遍历数组),则在调用 时不会获得预期值。所以是的,一定要在使用前打电话,以确保你得到你想要的东西。nextresetendkeyresetkey
15赞 Pupil 12/2/2011 #4

请找到以下内容:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys   =   array_keys($yourArray);
echo "Key = ".$keys[0];

工作示例:

21赞 Sergiy Sokolenko 4/12/2012 #5
list($firstKey) = array_keys($yourArray);

评论

3赞 Yada 5/12/2015
这可能不是最有效的。
3赞 Sergiy Sokolenko 5/13/2015
@Yada,是的,但这在极少数情况下可能会很明显;在大多数情况下,可读性和可维护性更为重要;我也更喜欢不改变原始对象/数组的解决方案:例如 reset($ar);$key = 键($ar);-- 并不总是好主意,我宁愿选择 MartyIX 的解决方案,它比我的解决方案更简洁,例如:array_keys($ar)[0];
12赞 Hamidreza 4/28/2012 #6
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1

评论

1赞 Hamidreza 7/25/2012
@jurgemaister剂量不返回 assoc 数组的第一个键。最大值 返回列表或数组项的最大值max()
5赞 d.raev 5/19/2014
不是 OP 请求,但在某些情况下非常有用。
10赞 Pupil 12/28/2012 #7

这也可能是一个解决方案:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$first_key = current(array_flip($yourArray));
echo $first_key;

我已经测试过了,它有效。

工作代码

评论

5赞 Mauro 2/8/2013
array_flip(): 只能翻转 STRING 和 INTEGER 值!
21赞 MartyIX 4/26/2013 #8

如果效率对你来说不是那么重要,你可以在 PHP 5.4(及更高版本)中使用。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)

IT)

评论

3赞 trante 5/17/2013
语法是否有效?array_keys($arr)[0]
5赞 MartyIX 5/17/2013
它位于 PHP 5.4 中。它被称为 .例如,请参阅:schlueters.de/blog/archives/...array dereferencing
0赞 Pacerier 2/17/2015
@trante,它适用于除 PHP < 5.4 之外的所有语言。
55赞 Webmut 1/20/2014 #9

有趣的是,foreach 循环实际上是最有效的方法。

由于OP专门询问了效率,因此应该指出的是,目前的所有答案实际上都远不如预言有效。

我用 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

reset+键 http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs

评论

3赞 flu 2/6/2014
你在某处有基准吗?比如你是如何测试的等等。无论如何,感谢您运行它们!
0赞 Jarda 8/11/2017
我想指出一个事实,即在整个测试过程中使用了相同的数组。我认为这一事实对 foreach 方法产生了重大影响。正如@donquixote在上面的一些响应的评论中提到的 - foreach 在内部复制数组。我可以想象在运行基准测试时会重用此副本,因为避免数组复制仅在此测试中提高了性能。
2赞 Webmut 8/12/2017
@Jarda 从 php7 开始,永远不要复制数组,除非你直接在 foreach 循环中修改它。在php5上,数组结构在某些情况下可以被复制(当它的引用计数>1时),你实际上是对的,它可能会对那里产生重大影响。幸运的是,在 php7 上没有什么可担心的,这个问题已经解决了。这里有一本很好的读物,介绍了 foreach 现在在引擎盖下的工作方式以及它过去的工作方式。foreach
2赞 But those new buttons though.. 6/28/2018
从 php7.2 开始,使用上述基准测试,foreach 仍然是最快的
4赞 voodoo417 1/25/2014 #10
 $arr = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
 list($first_key) = each($arr);
 print $first_key;
 // key1
37赞 Stopper 11/6/2014 #11

你可以试试

array_keys($data)[0]

评论

0赞 Sérgio 11/22/2022
恕我直言,这是正确的答案
0赞 Kohjah Breese 11/6/2015 #12

一句话:

$array = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
echo key( array_slice( $array, 0, 1, true ) );

# echos 'key1'
3赞 Yuriy Petrovskiy 2/17/2016 #13

对我有用的最好方法是

array_shift(array_keys($array))

array_keys从初始数组中获取键数组,然后从中剪切第一个元素值。 为此,您将需要 PHP 5.4+。array_shift

-1赞 Priyank 2/28/2017 #14

你可以玩你的阵列

$daysArray = array('Monday', 'Tuesday', 'Sunday');
$day = current($transport); // $day = 'Monday';
$day = next($transport);    // $day = 'Tuesday';
$day = current($transport); // $day = 'Tuesday';
$day = prev($transport);    // $day = 'Monday';
$day = end($transport);     // $day = 'Sunday';
$day = current($transport); // $day = 'Sunday';

要获取数组的第一个元素,您可以使用,对于最后一个元素,您可以使用currentend

编辑

只是为了不让更多的人对答案投反对票,您可以将键转换为值,如上所示。array_keys

评论

1赞 Victor Schröder 2/6/2018
这些是值,而不是键。
4赞 Salvi Pascual 3/31/2017 #15

这是我找到的最简单的方法。速度快,只需两行代码:-D

$keys = array_keys($array);
echo $array[$keys[0]];
0赞 Roupioz Clement 7/20/2017 #16

今天,我必须搜索 POST 请求返回的数组的第一个键。(并记下表单 ID 等的数字)

好吧,我发现了这个: 在PHP中返回关联数组的第一个键

http://php.net/key

我已经这样做了,而且它有效。

    $data = $request->request->all();
    dump($data);
    while ($test = current($data)) {
        dump($test);
        echo key($data).'<br />';die();
        break;
    }

也许它会生态另一个人的 15 分钟。 CYA的。

5赞 PrinsEdje80 9/13/2017 #17

为了增强 Webmut 的解决方案,我添加了以下解决方案:

$firstKey = array_keys(array_slice($array, 0, 1, TRUE))[0];

我在 PHP 7.1 上的输出是:

foreach to get first key and value: 0.048566102981567 seconds 
reset+key to get first key and value: 0.11727809906006 seconds 
reset+key to get first key: 0.11707186698914 seconds 
array_keys to get first key: 0.53917098045349 seconds 
array_slice to get first key: 0.2494580745697 seconds 

如果我对大小为 10000 的数组执行此操作,则结果变为

foreach to get first key and value: 0.048488140106201 seconds 
reset+key to get first key and value: 0.12659382820129 seconds 
reset+key to get first key: 0.12248802185059 seconds 
array_slice to get first key: 0.25442600250244 seconds 

array_keys方法在 30 秒时超时(只有 1000 个元素,其余元素的时间大致相同,但array_keys方法大约有 7.5 秒)。

30赞 Ivan Augusto 8/29/2018 #18

对于 2018+

从 PHP 7.3 开始,有一个功能可以实现这一点:
array_key_first()

$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
$firstKey = array_key_first($array); // 'foo'

文档可在此处获得。😉

3赞 Benjamin Beganović 12/4/2018 #19

PHP73的:

$array = ['a' => '..', 'b' => '..'];

array_key_first($array); // 'a'
array_key_last($array); // 'b';

http://php.net/manual/en/function.array-key-first.php

评论

1赞 MichaelvE 12/4/2018
包括解释确实有助于提高帖子的质量。请记住,您将来正在为读者回答问题,而这些人可能不知道您的代码建议的原因
-1赞 Javed Khan 8/13/2020 #20

用:

$array = ['po','co','so'];

echo reset($array); 

结果 : po

0赞 Fabián Fernández 8/25/2020 #21

我认为最好和最快的方法是:

$first_key=key(array_slice($array, 0, 1, TRUE))
2赞 AndreyP 10/23/2020 #22

从 PHP 7.3.0 开始,可以使用函数 array_key_first()。

有几种方法可以为 PHP 7.3.0 之前的版本提供此功能。可以使用,但效率可能相当低。也可以使用 和 ,但这可能会更改内部数组指针。一个有效的解决方案,它不改变内部数组指针,写成 polyfill:array_keys()reset()key()

<?php
if (!function_exists('array_key_first')) {
    function array_key_first(array $arr) {
        foreach($arr as $key => $unused) {
            return $key;
        }

        return null;
    }
}
?>
2赞 Shahroq 3/17/2021 #23

关于@Blixt答案,在 7.3.0 之前,可以使用此 polyfill:

if (!function_exists('array_key_first')) {
  function array_key_first(array $array) {
    return key(array_slice($array, 0, 1, true));
  }
}
1赞 Pijush Gupta 12/3/2021 #24

这将适用于所有PHP版本

$firstKey = '' ;

//$contact7formlist - associative array. 

if(function_exists('array_key_first')){
    
    $firstKey = array_key_first($contact7formlist);
    
}else{
    
    foreach ($contact7formlist as $key => $contact7form ){
        $firstKey = $key;
        break;
    }
}
0赞 Mauister 1/29/2022 #25

array_chunk将数组拆分为块,可以使用:

$arr = ['uno'=>'one','due'=>'two','tre'=>'three'];
$firstElement = array_chunk($arr,1,true)[0];
var_dump($firstElement);