获取数组的第一个元素


1071

我有一个数组:

array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )

我想获得此数组的第一个元素。预期结果:字符串 apple

一个要求:它不能通过引用传递来完成,所以array_shift不是一个好的解决方案。

我怎样才能做到这一点?


1
你是什​​么意思,不能参考吗?
cjk

函数不应&$array用作参数。
hsz

4
我怀疑您“真正”的意思是“无法通过引用完成”,是您的数组是从数据库动态返回的,并且您不想在采用第一个元素之前将数组传递给变量从中。如果我是对的,那么下面提供给您的所有解决方案(包括已接受的答案)中的绝大多数都不足够。
cartbeforehorse 2012年

您是否只需要获取它或将其从现有阵列中删除?
Jo Smo 2014年

对于数组的基本用法,您可以查看以下链接technofusions.com/introduction-to-arrays-in-php
Vikrant Vir Bhalla

Answers:


1367

原始答案,但代价昂贵(O(n)):

array_shift(array_values($array));

在O(1)中:

array_pop(array_reverse($array));

其他用例等

如果修改(就重置数组指针而言)$array不是问题,则可以使用:

reset($array);

如果需要数组“副本”,则从理论上讲应该更有效:

array_shift(array_slice($array, 0, 1));

使用PHP 5.4+(但如果为空,则可能导致索引错误):

array_values($array)[0];

77
+1是一个聪明的解决方法,可以防止使用array_values()修改原始数组
ChrisR 2011年

44
我明白了:<b>严格标准</ b>:只有变量应该通过引用传递。不错的解决方法顺便说一句
Simone

191
这是不是有点矫?过正?如果数组包含数千个元素怎么办?创建一个全新的数组以获取其第一个元素是否合理?list()reset()是我的意见好得多的解决方案。
马丁·迪米特罗夫

33
我同意。与重置并返回当前值的一行相比,总的过度杀伤力和非凡的资源消耗很大:reset($ array);
zmonteca 2012年

48
-1如上述评论者所述。令人难以置信的是,它有101次投票。
Lightness Races in Orbit

789

正如Mike指出的(最简单的方法):

$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
echo reset($arr); // Echoes "apple"

如果要获取密钥:(重置后执行)

echo key($arr); // Echoes "4"

PHP的文档中

混合 重置(array &$ array);

描述:

reset()将数组的内部指针后退到第一个元素,并返回第一个数组元素的值;如果数组为空,则返回FALSE。


尽管通过引用传递了它以进行重置,但原始数组没有被修改。我猜这就是hsz不想通过引用传递它的原因..?
丹尼斯·贾明

10
数组的迭代器已修改。如果foreach对主题数组执行此操作,则将其弄糟。
Zenexer

2
@Zenexer这并不总是(通常)正确。通常在实践中,foreach将复制它循环通过的数组。
路加·考辛斯

1
@Angger重置后,您可以拨打电话key($arr),您会得到'4'(添加到答案中)
lepe

3
@Zenexer和Luke Cousins都不正确:1)foreach不使用数组的内部指针-而是创建它自己的指针。检查foreach内部的reset很容易-循环将遵循它的方式,而不会影响reset()。2)不,foreach不会创建数组的副本!!!它只会创建自己的指针(甚至不创建现有指针的副本-也很容易检查,next()在foreach之前调用)。
dmikam '18年

278
$first_value = reset($array); // First element's value
$first_key = key($array); // First element's key

2
我没有实际测试过,但是看来这种方法是最有效的。
mason81年

4
唯一的问题是要问的是价值,而不是关键。因此,应使用current($ array)代替key($ array)
zmonteca 2012年

4
@zmonteca $ first_value =重置($ array); 在这里,您可以获得值,reset()函数后退数组内部指针并返回第一个元素。
S3Mi 2012年

1
最好的答案!在寻找key()等效项以获取第一个值。这有帮助!
Alain Tiemblo 2012年

98
$arr = array( 9 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($arr); // echoes 'apple'

如果您不想丢失当前的指针位置,只需为数组创建一个别名。


1
没明白,你是什么意思?是否第一个的密钥大于其他的密钥,效果很好。
yoda

29
+1 FYI reset()已经返回了第一个元素,因此无需使用current()- echo reset($arr)应该足够
Mike

@Mike但您可能更currentreset避免PHP通知/参考的情况下产生的错误,例如current(array_filter(...));在3v4l
CPHPython

91

current($array)根据PHP手册,您可以获取数组的第一个元素。

每个数组都有一个指向其“当前”元素的内部指针,该指针被初始化为插入该数组的第一个元素。

因此,它一直有效,直到您重新放置了数组指针为止,否则必须重置数组。


4
我不知道为什么这不是公认的答案,因为它相当简单,准确地回答了问题。
2014年

26
current($array)仅当数组指针“当前”指向第一个元素时才有效,否则reset($array)将是必需的。
2015年

6
似乎current()不再需要参考,尽管PHP文档没有反映出这一点。因此,我认为这已成为最佳解决方案。
瑞安

@Ryan同意,但是这个解决方案是在2014年之前2年在同一线程的其他答案中给出的。
CPHPython

70

您可以使用语言构造“列表”获得第N个元素:

// First item
list($firstItem) = $yourArray;

// First item from an array that is returned from a function
list($firstItem) = functionThatReturnsArray();

// Second item
list( , $secondItem) = $yourArray;

使用此array_keys功能,您可以对按键执行相同的操作:

list($firstKey) = array_keys($yourArray);
list(, $secondKey) = array_keys($yourArray);

2
这正是我所做的:list($first_value) = $my_array;我认为,这是最好的选择。它没有此处提供的其他答案的问题:没有“过大杀伤力”,因为它不会复制或阵列或创建新阵列。无“引用”:数组未修改。没有“重置”:数组内部指针没有更改...
J. Bruni

6
非常优雅的解决方案,但在数组为空时抛出E_NOTICE。
Tgr

1
@Mike是的,但是后来就不再那么优雅了:)
Tgr

13
这不是吗?它仅在使用数组键的情况下起作用int,然后尝试执行list($firstItem) = array('key1' => 'value1');,您将得到一个错误Notice: Undefined offset: 0
Marco Demaio

12
澄清list($x) = foo();一下:等同于$x = foo()[0];。请注意,这不一定与“获取第一项”相同,因为即使是整数索引数组也可能没有键0的元素。在我的情况下,我正在执行“ list($ order)= get_order($ user) ;“ 但是“ get_order”返回的是由其ID键入的订单,通常不为0。正如@Sergiy所说,array_values()可以解决此问题,但是会降低代码的效率和(更重要的是)可读性。
Warbo,


38

PHP 7.3添加了两个函数,可直接获取数组的第一个和最后一个键,而无需修改原始数组,也无需创建任何临时对象:

除了在语义上有意义之外,这些函数甚至都不会移动数组指针(就像foreach那样)。

有了键,就可以直接通过键获取值。


示例(它们都需要PHP 7.3+)

获取第一个/最后一个键和值:

$my_array = ['IT', 'rules', 'the', 'world'];

$first_key = array_key_first($my_array);
$first_value = $my_array[$first_key];

$last_key = array_key_last($my_array);
$last_value = $my_array[$last_key];

假设数组不能为空,则将第一个/最后一个值作为单线获取:

$first_value = $my_array[ array_key_first($my_array) ];

$last_value = $my_array[ array_key_last($my_array) ];

以单线获取第一个/最后一个值,默认值为空数组:

$first_value = empty($my_array) ? 'default' : $my_array[ array_key_first($my_array) ];

$last_value = empty($my_array) ? 'default' : $my_array[ array_key_last($my_array) ];

使用null-coalescing运算符来缩短,通常默认为null,因此: $first_value = $my_array[array_key_first($my_array)] ?? null;
Mitchell McKenna

29

假设:

$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

只需使用:

$array[key($array)]

获得第一个元素或

key($array)

获得第一把钥匙。

或者,如果您要删除第一个链接,则可以取消链接。


9
岂不是简单地使用current呢?
Marco Demaio 2013年

27

某些阵列不工作与功能,如listresetcurrent。也许它们是“伪”数组-例如,部分实现ArrayIterator。

如果要不管数组而拉第一个值,都可以使迭代器短路:

foreach($array_with_unknown_keys as $value) break;

您的值将在其中可用,$value并且循环将在第一次迭代后中断。这比将潜在的大型数组复制到array_unshift(array_values($ arr))之类的函数效率更高。

您也可以通过这种方式获取密钥:

foreach($array_with_unknown_keys as $key=>$value) break;

如果要从函数调用此函数,只需提前返回:

function grab_first($arr) {
    foreach($arr as $value) return $value;
}

我认为这是最快的方法之一,因为使用语言结构foreach而不是函数调用(这更昂贵)。 designcise.com/web/tutorial/...
伊尔达·Amankulov

19

Laravel的助手那里

function head($array)
{
    return reset($array);
}

数组通过值传递给函数,reset()影响数组副本的内部指针,并且它不接触原始数组(请注意,false如果数组为空,则返回该数组)。

用法示例:

$data = ['foo', 'bar', 'baz'];

current($data); // foo
next($data); // bar
head($data); // foo
next($data); // baz

另外,这是一种替代方法。这是非常轻微快,但更有趣。如果数组为空,则可以轻松更改默认值:

function head($array, $default = null)
{
    foreach ($array as $item) {
        return $item;
    }
    return $default;
}

为了记录,这是我的另一个答案,是数组的最后一个元素。


17

保持简单!这里有很多正确的答案,但是为了最大程度地减少所有的混乱,这两个工作并减少了很多开销:

key($array)获取数组的第一个键
current($array)获取数组的第一个值


编辑:
关于下面的评论。以下示例将输出:string(13) "PHP code test"

$array = array
(
   '1'           => 'PHP code test',  
   'foo'         => 'bar', 5 , 5 => 89009, 
   'case'        => 'Random Stuff: '.rand(100,999),
   'PHP Version' => phpversion(),
   0             => 'ending text here'
);

var_dump(current($array));

11
current等于当前元素。您必须将指针重置为数组的开头,以确保它实际上位于数组的开头。
waterloomatt

current()将获取当前元素,而不是第一个元素。这是不同的。
Amirhossein Tarmast

如果数组中只有一个元素,那么current将起作用。
Zameer Fouzan


14

我会的echo current($array)


1
@hsz没关系,current()传递非引用时也不会出错。前提是指针仍处于开始状态。
丹·拉格

但是它会产生一个通知,使您的日志变得脏又好...如果不重要,还应该删除通知
dmikam 2015年

1
@dmikam不,不是。实际上reset不会产生“仅应通过引用传递变量”的通知,而current不会:的在线PHP编辑器示例current(array_filter(...));
CPHPython

@CPHPython,似乎您是对的...好像我对PHP 4的旧版本有当前的想法,它确实会产生致命错误:sandbox.onlinephpfunctions.com/code/… 我在使用current时看到的唯一问题是它不能保证返回的元素是数组的第一个元素(内部指针可以由调用的函数修改)。实际上,它可以返回数组的随机元素。
dmikam '18年

1
@CPHPython有点做作的例子,但它说明以及我的想法:sandbox.onlinephpfunctions.com/code/... 试想一下,你从一些功能收到您的阵列使用next()end()或其他任何功能修改阵列的内部指针。在我的示例中,current()由于内部指针不在数组的范围内,因此返回null。但这也可能“虚拟地”指向任何/随机元素。
dmikam '18年

13
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
foreach($arr as $first) break;
echo $first;

输出:

apple

10
$myArray = array (4 => 'apple', 7 => 'orange', 13 => 'plum');
$arrayKeys = array_keys($myArray);

// The first element of your array is:
echo $myArray[$arrayKeys[0]];

我没有按照公认的答案中的描述进行操作。用过的谢谢
JayKandari 2014年

9
$array=array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

$firstValue = each($array)[1];

这比array_values()因为该each()函数不复制整个数组要有效得多。

有关更多信息,请参见http://www.php.net/manual/zh/function.each.php


because the each() function does not copy the entire array.+1

2
但事实是,您应该在之前进行重置,如果内部指针不在开始位置,那么您将不会获得第一个元素。
卡洛斯·戈斯

但是each()通过引用接收一个数组,初始问题的要求不是这样做的
dmikam 2015年

8

一种笨拙的方法是:

$foo = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

function get_first ($foo) {
    foreach ($foo as $k=>$v){
        return $v;
    }
}

print get_first($foo);

3
至少你是诚实的-这很糊涂!但是,它起作用了,在学习上面的list()技术之前,我一直使用它。
random_user_name 2013年

1
如果执行此操作,则最好还是reset()foreach调用数组指针之前将其重置。
Tyzoid 2014年

7

获取第一个元素:

array_values($arr)[0]

获取最后一个元素

array_reverse($arr)[0]

数字键通过array_reverse保留,因此仍将返回第一个元素。3v4l.org/2729s
不要惊慌

7

这些工作大部分!但是可以进行快速单行(资源较少)的调用:

$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo $array[key($array)];

// key($array) -> will return the first key (which is 4 in this example)

尽管这行之有效,而且还不错,但也请参阅我的其他答案:https : //stackoverflow.com/a/48410351/1804013


5
这等效于using current($array),它要求数组的内部指针始终位于第一个元素处,在这种情况下,echo reset($array)最合适。
Tyzoid 2014年

@Tyzoid他实际上在这里用您的建议写了另一个答案,但他省略了您的解释...谢谢。
CPHPython

@Tyzoid:我又做了一个额外的答案/更新:stackoverflow.com/a/48410351/1804013
tfont

5

我认为使用array_values将是您最好的选择。您可以从该函数的结果返回索引零处的值以获取“ apple”。


5

这对游戏来说有点晚了,但是我遇到了一个问题,我的数组在其中包含作为子元素的数组元素,因此我不能只获得第一个数组元素的字符串表示形式。通过使用PHP的current()功能,我对此进行了管理:

<?php
    $original = array(4 => array('one', 'two'), 7 => array('three', 'four'));
    reset($original);  // to reset the internal array pointer...
    $first_element = current($original);  // get the current element...
?>

感谢所有当前的解决方案帮助我获得了这个答案,希望这对某人有所帮助!


4

采用:

$first = array_slice($array, 0, 1);  
$val= $first[0];

默认情况下,array_slice不保留键,因此我们可以安全地使用零作为索引。


4

为您提供两种解决方案。

解决方案1-只需使用钥匙。您没有说不能使用它。:)

<?php
    // Get the first element of this array.
    $array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

    // Gets the first element by key
    $result = $array[4];

    // Expected result: string apple
    assert('$result === "apple" /* Expected result: string apple. */');
?>

解决方案2-array_flip()+ key()

<?php
    // Get first element of this array. Expected result: string apple
    $array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

    // Turn values to keys
    $array = array_flip($array);

    // You might thrown a reset in just to make sure
    // that the array pointer is at the first element.
    // Also, reset returns the first element.
    // reset($myArray);

    // Return the first key
    $firstKey = key($array);

    assert('$firstKey === "apple" /* Expected result: string apple. */');
?>

解决方案3-array_keys()

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

2

在现实世界中,这并不是那么简单的反应。假设我们有一些可能的响应示例,您可以在某些库中找到这些示例。

$array1 = array();
$array2 = array(1,2,3,4);
$array3 = array('hello'=>'world', 'foo'=>'bar');
$array4 = null;

var_dump('reset1', reset($array1));
var_dump('reset2', reset($array2));
var_dump('reset3', reset($array3));
var_dump('reset4', reset($array4)); // Warning

var_dump('array_shift1', array_shift($array1));
var_dump('array_shift2', array_shift($array2));
var_dump('array_shift3', array_shift($array3));
var_dump('array_shift4', array_shift($array4)); // Warning

var_dump('each1', each($array1));
var_dump('each2', each($array2));
var_dump('each3', each($array3));
var_dump('each4', each($array4)); // Warning

var_dump('array_values1', array_values($array1)[0]); // Notice
var_dump('array_values2', array_values($array2)[0]);
var_dump('array_values3', array_values($array3)[0]);
var_dump('array_values4', array_values($array4)[0]); // Warning

var_dump('array_slice1', array_slice($array1, 0, 1));
var_dump('array_slice2', array_slice($array2, 0, 1));
var_dump('array_slice3', array_slice($array3, 0, 1));
var_dump('array_slice4', array_slice($array4, 0, 1)); // Warning

list($elm) = $array1; // Notice
var_dump($elm);
list($elm) = $array2;
var_dump($elm);
list($elm) = $array3; // Notice
var_dump($elm);
list($elm) = $array4;
var_dump($elm);

如您所见,我们有几种“一线式”解决方案在某些情况下(但并非在所有情况下)都能很好地工作。

在我看来,您应该只使用数组处理程序。

现在讨论性能,假设我们总是数组,如下所示:

$elm = empty($array) ? null : ...($array);

...you would use without errors:
$array[count($array)-1];
array_shift
reset
array_values
array_slice

array_shift快于reset,比[count()-1]快,而这三个比array_values和快array_slice


2

我想象作者只是在寻找一种从某个函数(例如mysql_fetch_row)获取数组后获取数组第一个元素而不生成STRICT的方法“仅应通过引用传递变量”。

如果是这样,这里描述的几乎所有方法都将得到此消息...,其中一些方法会使用大量额外的内存来复制数组(或数组的一部分)。避免这种情况的一种简单方法是在调用以下任何函数之前直接内联分配值:

$first_item_of_array = current($tmp_arr = mysql_fetch_row(...));
// or
$first_item_of_array = reset($tmp_arr = func_get_my_huge_array());

这样,您既不会在屏幕上也不会在日志中看到STRICT消息,也不会创建任何其他数组。它适用于索引和关联数组。


1

我喜欢“列表”示例,但“列表”仅适用于作业的左侧。如果我们不想分配变量,我们将被迫组成一个临时名称,该名称充其量会污染我们的范围,而最糟糕的是会覆盖现有值:

list($x) = some_array();
var_dump($x);

上面的代码将覆盖$ x的任何现有值,并且只要该作用域处于活动状态(此函数/方法的末尾,或者如果我们位于顶层,则永久保留),$ x变量就会徘徊。可以使用call_user_func和匿名函数来解决此问题,但这很笨拙:

var_dump(call_user_func(function($arr) { list($x) = $arr; return $x; },
                        some_array()));

如果我们使用这样的匿名函数,即使它们使用了按引用传递,我们实际上也可以避免使用reset和array_shift。这是因为调用函数将绑定其参数,并且这些参数可以通过引用传递:

var_dump(call_user_func(function($arr) { return reset($arr); },
                        array_values(some_array())));

但是,这实际上是多余的,因为call_user_func将在内部执行此临时分配。这使我们可以将按引用传递函数视为按值传递,而不会出现任何警告或错误:

var_dump(call_user_func('reset', array_values(some_array())));

1

Sarfraz发布的内容有一个小变化:

$array = array(1, 2, 3, 4, 5);
$output = array_slice($array, 0, 1);
print_r ($output);

1

我不喜欢摆弄数组的内部指针,但是用array_keys()或构建第二个数组效率也不高array_values(),所以我通常定义如下:

function array_first(array $f) {
    foreach ($f as $v) {
        return $v;
    }
    throw new Exception('array was empty');
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.