ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

为什么foreach效率低下?
与所有答案相比,foreach 仍然是最快的FIDDLE, PHP 5.3,我在 PHP 5.5 上的 localhost 测试表明,差异稍微有利于 foreach。
@Danijel,foreach 在语义上是错误的。
@AlexS,each($arr)['key']each($arr)[0] 都可以。
@Danijel 不再...键:0.0107,foreach:0.0217

M
Matt Kieran

2019 更新

PHP 7.3 开始,有一个名为 array_key_first() 的新内置函数,它将从给定数组中检索第一个键,而无需重置内部指针。查看 documentation 了解更多信息。

您可以使用 resetkey

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() 也恰好返回任何数组的第一个元素(值,而不是键),这也很方便。
reset() 的文档中有一条评论说 Don't use reset()` 以获取关联数组的第一个值。它适用于真正的数组,但在 Iterator 对象上却出人意料。 bugs.php.net/bug.php?id=38478` 这仍然是真的吗?我很困惑
@DmitryPashkevich:不要担心那个评论。他们不是在谈论 array 对象,而是自定义对象(不是实际的数组)。我猜他们混淆了数据结构的差异,但基本上,reset 返回第一个“键”的值,在“错误”报告中给出的示例中,对象将是 $prop,但对于数组第一把钥匙。所以不用担心,只要您使用真正的数组(使用 array(…) 创建),就不会出现问题。
应该提到 end() 和 reset() 有一个副作用。然而,世界上大多数代码并不依赖于内部指针在任何地方,所以这通常不是问题。
@user3019105 每个数组只有一个内部指针,这意味着如果您的函数之外的任何代码更改它(通过调用 nextresetend 或遍历数组),您将无法获得预期调用 key 时的值。所以是的,在使用 key 之前始终调用 reset 以确保您得到您想要的。
t
troelskn

array_keys 返回一个键数组。取第一个条目。或者,您可以调用阵列上的 reset,然后调用 key。后一种方法可能稍微快一些(虽然我没有测试它),但它具有重置内部指针的副作用。


只是给未来读者的一个(迟到的)说明:后一种方法不仅仅是“稍微”快一些。迭代整个数组、将每个键存储在另一个新创建的数组中以及将数组的第一个键请求为字符串之间存在很大差异。
为什么与所有这些答案相比,问题中的操作效率低下?
@EmilioGort 好问题。我认为实际上 foreach + breakreset + key 的性能没有任何区别。但前者看起来很奇怪,所以对于风格问题,我更喜欢后者。
@EmilioGort:Afaik, foreach() 在内部复制数组。所以我们可以假设它更慢。 (如果有人能证实这一点会很好)
@donquixote 我不确定,但假设它是一个常规数组(而不是实现某种类型或 Iterator 接口的对象),我相当确定 foreach 不会为其创建内部副本,而只是迭代一个指针,类似于使用更底层的 nextcurrent 等。
W
Webmut

有趣的是,foreach 循环实际上是执行此操作的最有效方式。

由于 OP 专门询问了效率,因此应该指出,所有当前的答案实际上都比 foreach 效率低得多。

我使用 php 5.4 对此进行了基准测试,重置/键指针方法(已接受的答案)似乎比 foreach 慢 7 倍。其他操作整个数组(array_keys、array_flip)的方法显然比这更慢,并且在处理大型数组时变得更糟。

Foreach 一点也不低效,请随意使用!

编辑 2015-03-03:

已请求基准脚本,我没有原始脚本,而是做了一些新的测试。这次我发现 foreach 的速度只有 reset/key 的两倍左右。我使用了一个 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


你在某处有基准吗?就像您如何测试等一样。无论如何,感谢您运行它们!
我想指出一个事实,即在整个测试中使用了相同的数组。我认为这一事实显着影响了 foreach 方法。正如@donquixote 在对上述某些回复的评论中提到的那样 - foreach 在内部复制了数组。我可以想象在运行基准测试时会重用这个副本,因为避免数组复制只会在这个测试中提高性能。
@Jarda 从 php7 开始,foreach 永远不会复制数组,除非您在 foreach 循环中直接修改它。在 php5 上,在某些情况下可以复制数组结构(当它的 refcount > 1 时),您实际上是对的,它可能在那里产生重大影响。幸运的是,在解决此问题的 php7 上无需担心。 Here 很好地了解了 foreach 现在是如何工作的,以及它过去是如何工作的。
从使用上述基准的 php7.2 开始,foreach 仍然是最快的
j
jimyi

key($an_array) 将为您提供第一把钥匙

根据 Blixt 进行编辑:您应该在 key($an_array) 之前调用 reset($array); 以将指针重置为数组的开头。


请记住,数组的指针可能不在第一个元素处,请参阅我的答案。
我认为这个答案将在不重置的情况下帮助我的情况,因为我首先要确保数组只有一个元素。谢谢
P
Pang

你可以试试

array_keys($data)[0]

i
ivanaugustobd

2018+

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

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

提供文档here。 😉


S
Sergiy Sokolenko
list($firstKey) = array_keys($yourArray);

这可能不是最有效的。
@Yada,是的,但这在极少数情况下可能会很明显;在大多数情况下,可读性和可维护性更为重要;而且我也更喜欢不会改变原始对象/数组的解决方案:例如 reset($ar); $key = key($ar); -- 并不总是好主意,我宁愿选择 MartyIX 的解决方案,它比我的更简洁,例如:array_keys($ar)[0];
M
MartyIX

如果效率对您来说不是那么重要,您可以在 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))。

高温高压


array_keys($arr)[0] 语法是否有效?
它在 PHP 5.4 中。它称为 array dereferencing。参见例如:schlueters.de/blog/archives/…
@trante,除了 PHP < 5.4 之外,它在所有语言中都有效。
P
Pupil

请找到以下内容:

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

Working Example:


H
Hamidreza
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1

@jurgemaister max() 不会返回 assoc 数组的第一个键。 max 返回列表或数组项的最大值
不是 OP 请求,但在某些情况下非常有用。
A
Arsen Khachaturyan

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

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

我已经对其进行了测试,并且可以正常工作。

Working Code


array_flip():只能翻转 STRING 和 INTEGER 值!
P
PrinsEdje80

为了增强 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 秒)。


v
voodoo417
 $arr = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
 list($first_key) = each($arr);
 print $first_key;
 // key1

S
Salvi Pascual

这是我发现的最简单的方法。快速且只有两行代码:-D

$keys = array_keys($array);
echo $array[$keys[0]];

Y
Yuriy Petrovskiy

对我有用的最好方法是

array_shift(array_keys($array))

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


B
Benjamin Beganović

php73:

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

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

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


包括解释确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而那些人可能不知道您的代码建议的原因
A
AndreyP

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

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

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

        return null;
    }
}
?>

S
Shahroq

回复@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));
  }
}

P
Pijush Gupta

这适用于所有 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;
    }
}

K
Kohjah Breese

单线:

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

# echos 'key1'

C
Chris Stadler

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

好吧,我发现了这个:Return first key of associative array in PHP

http://php.net/key

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

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

也许它会让另一个人生态 15 分钟。氰化物。


F
Fabián Fernández

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

$first_key=key(array_slice($array, 0, 1, TRUE))

T
Toto

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

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

P
Priyank

你可以玩你的阵列

$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';

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

编辑

只是为了不再对答案投反对票,您可以使用 array_keys 将您的键转换为值并使用如上所示。


这些是值,而不是键。
J
Javed Khan

利用 :

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

echo reset($array); 

结果:宝