PHP Conference Japan 2024

array_shift

(PHP 4, PHP 5, PHP 7, PHP 8)

array_shift从数组开头移出元素

描述

array_shift(数组 &$array): 混合

array_shift()array 的第一个值移出并返回,缩短 array 一个元素并将所有内容向下移动。所有数字数组键将被修改为从零开始计数,而文字键不会受到影响。

注意: 此函数将在使用后reset() 输入数组的数组指针。

参数

array

输入数组。

返回值

返回移出的值,如果 array 为空或不是数组,则返回 null

示例

示例 #1 array_shift() 示例

<?php
$stack
= array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
?>

以上示例将输出

Array
(
    [0] => banana
    [1] => apple
    [2] => raspberry
)

并且 orange 将被赋值给 $fruit

参见

添加注释

用户贡献的注释 29 条注释

regs at voidship dot net
16 年前
在较大的数组上使用 array_shift 速度相当慢。随着数组缩小,速度加快,很可能是因为它必须重新索引较小的数据集。

对于我的目的,我使用了 array_reverse,然后是 array_pop,它不需要重新索引数组,如果需要,它会保留键(在我的情况下无关紧要)。

使用直接索引引用,即 array_test[$i],速度很快,但用于破坏性操作的直接索引引用 + unset 与 array_reverse 和 array_pop 的速度大致相同。它还需要连续的数字键。
elad dot yosifon at gmail dot com
11 年前
注意
array_pop() 的复杂度为 O(1)。
array_shift() 的复杂度为 O(n)。
array_shift() 需要对数组进行重新索引过程,因此它必须遍历所有元素并对其进行索引。
nospam at dyce dot losethisbit dot com
16 年前
只是一个返回带有第一个键和值的简单数组的有用版本。可能还有更好的方法,但它对我有用 ;-)

<?php

function array_kshift(&$arr)
{
list(
$k) = array_keys($arr);
$r = array($k=>$arr[$k]);
unset(
$arr[$k]);
return
$r;
}

// 在一个简单的关联数组上测试它
$arr = array('x'=>'ball','y'=>'hat','z'=>'apple');

print_r($arr);
print_r(array_kshift($arr));
print_r($arr);

?>

输出

数组
(
[x] => ball
[y] => hat
[z] => apple
)
数组
(
[x] => ball
)
数组
(
[y] => hat
[z] => apple
)
biziclop at vipmail dot hu
6 年前
<?php

// 使用 array_pop/shift/push/unshift 操作非连续索引数组时需谨慎:

$shifty = $poppy = array(
2 => '(2)',
1 => '(1)',
0 => '(0)',
);
print_r( $shifty );

array_shift( $shifty ); print_r( $shifty );
// [0] => (1)
// [1] => (0)

array_pop( $poppy ); print_r( $poppy );
// [2] => (2)
// [1] => (1)

$shifty = $poppy = array(
'a' => 'A',
'b' => 'B',
'(0)',
'(1)',
'c' => 'C',
'd' => 'D',
);
print_r( $shifty );

array_shift( $shifty ); print_r( $shifty );
// [b] => B
// [0] => (0)
// [1] => (1)
// [c] => C
// [d] => D

array_unshift( $shifty, 'unshifted'); print_r( $shifty );
// [0] => unshifted
// [b] => B
// [1] => (0)
// [2] => (1)
// [c] => C
// [d] => D

array_pop( $poppy ); print_r( $poppy );
// [a] => A
// [b] => B
// [0] => (0)
// [1] => (1)
// [c] => C

array_push( $poppy, 'pushed'); print_r( $poppy );
// [a] => A
// [b] => B
// [0] => (0)
// [1] => (1)
// [c] => C
// [2] => pushed

?>
chris {at} w3style {dot} co {dot} uk
16 年前
如前所述,在 PHP4 中,array_shift() 通过引用修改输入数组,但它不通过引用返回第一个元素。这看起来可能非常出乎意料。如果您正在处理引用集合(在我的例子中是 XML 节点),则此方法应该可以解决问题。

<?php

/**
* 此函数与 array_shift() 的行为相同,除了
* 它返回对数组第一个元素的引用,而不是副本。
*
* @param array &$array
* @return mixed
*/
function &array_shift_reference(&$array)
{
if (
count($array) > 0)
{
$key = key($array);
$first =& $array[$key];
}
else
{
$first = null;
}
array_shift($array);
return
$first;
}

class
ArrayShiftReferenceTest extends UnitTestCase
{

function
testFunctionRemovesFirstElementOfNumericallyIndexedArray()
{
$input = array('foo', 'bar');
array_shift_reference($input);
$this->assertEqual(array('bar'), $input, '%s: 数组应该向左移动一个元素');
}

function
testFunctionRemovesFirstElementOfAssociativeArray()
{
$input = array('x' => 'foo', 'y' => 'bar');
array_shift_reference($input);
$this->assertEqual(array('y' => 'bar'), $input, '%s: 数组应该向左移动一个元素');
}

function
testFunctionReturnsReferenceToFirstElementOfNumericallyIndexedArray()
{
$foo = 'foo';
$input = array(&$foo, 'bar');
$first =& array_shift_reference($input);
$this->assertReference($foo, $first, '%s: 返回值应引用第一个数组元素');
}

function
testFunctionReturnsReferenceToFirstElementOfAssociativeArray()
{
$foo = 'foo';
$input = array('x' => &$foo, 'y' => 'bar');
$first =& array_shift_reference($input);
$this->assertReference($foo, $first, '%s: 返回值应引用第一个数组元素');
}

function
testFunctionReturnsNullIfEmptyArrayPassedAsInput()
{
$input = array();
$first = array_shift_reference($input);
$this->assertNull($first, '%s: 数组没有第一个元素,因此应返回 NULL');
}

}

?>
michaeljanikk at gmail dot com
10 年前
从数组中间移除一个元素(类似于 array_shift,只是我们想要移除中间的元素而不是第一个元素,并将后续的所有键向下移动一个位置)

请注意,这仅适用于枚举数组。

<?php
$array
= array('a', 'b', 'c', 'd', 'e', 'e');
/*
array(6) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
[3]=>
string(1) "d"
[4]=>
string(1) "e"
[5]=>
string(1) "e"
}
*/

$indexToRemove = 2;
unset(
$array[$indexToRemove]);
$array = array_slice($array, 0);

/*
array(5) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "d"
[3]=>
string(1) "e"
[4]=>
string(1) "e"
}
*/
?>

希望这对某些人有所帮助!
mah dot di at live dot com
8 年前
此 removeAdd 函数,第一个参数将数组左移,然后将第二个参数左插到数组中。第一个参数是数组,第二个参数可以是整数或字符串。

<?php
function removeAdd ($arr, $newer){
$a = array_shift($arr);
$b = array_unshift($arr, $newer);
foreach (
$arr as $value){
echo
$value."<br />";
}
}

$a = array(1,2,3,4,5,6);
foreach (
$a as $current){
echo
$current."<br />";
}
echo
"<hr />";
removeAdd($a, 0);
?>

输出
1
2
3
4
5
6
_______

0
2
3
4
5
6
陷阱
17 年前
对于那些可能尝试对包含引用的数组使用 array_shift() 的人(例如,使用链接节点树),请注意 array_shift() 可能无法按预期工作:它将返回数组第一个元素的*副本*,而不是元素本身,因此您的引用将丢失。

解决方案是在使用 array_shift() 删除之前引用第一个元素。

<?php

// 只使用 array_shift:
$a = 1;
$array = array(&$a);
$b =& array_shift($array);
$b = 2;
echo
"a = $a, b = $b<br>"; // 输出 a = 1, b = 2

// 解决方案:首先引用第一个元素:
$a = 1;
$array = array(&$a);
$b =& $array[0];
array_shift($array);
$b = 2;
echo
"a = $a, b = $b<br>"; // 输出 a = 2, b = 2

?>
arturo {dot} ronchi {at} gmail {dot} com
19 年前
如果您想获取顶部元素并在之后旋转数组,这里有一个小函数。

function array_rotate(&$arr)
{
$elm = array_shift($arr);
array_push($arr, $elm);
return $elm;
}
匿名用户
19 年前
此函数将保存数组的键值,并且它将在较低版本的 PHP 中工作。

<?php

function array_shift2(&$array){
reset($array);
$key = key($array);
$removed = $array[$key];
unset(
$array[$key]);
return
$removed;
}

?>
patrick at pwfisher dot com
15 年前
这是一个用于解析命令行参数的实用程序函数。

<?php
/**
* CommandLine 类
*
* @package Framework
*/
/**
* 命令行界面 (CLI) 实用程序类。
*
* @author Patrick Fisher <[email protected]>
* @since 2009 年 8 月 21 日
* @package Framework
* @subpackage Env
*/
class CommandLine {

/**
* 解析参数
*
* [pfisher ~]$ echo "<?php
* > include('CommandLine.php');
* > \$args = CommandLine::parseArgs(\$_SERVER['argv']);
* > echo "\n", '\$out = '; var_dump(\$args); echo "\n";
* > ?>" > test.php
*
* [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --alsofunny=spam=eggs \
* > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s
*
* $out = array(12) {
* [0] => string(9) "plain-arg"
* ["foo"] => bool(true)
* ["bar"] => string(3) "baz"
* ["funny"] => string(9) "spam=eggs"
* ["alsofunny"] => string(9) "spam=eggs"
* [1] => string(11) "plain arg 2"
* ["a"] => bool(true)
* ["b"] => bool(true)
* ["c"] => bool(true)
* ["k"] => string(5) "value"
* [2] => string(11) "plain arg 3"
* ["s"] => string(9) "overwrite"
* }
*
* @author Patrick Fisher <[email protected]>
* @since 2009 年 8 月 21 日
* @see https://php.net/manual/en/features.commandline.php
* #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008
* #78651 function getArgs($args) by B Crawford, 22-Oct-2007
* @usage $args = CommandLine::parseArgs($_SERVER['argv']);
*/
public static function parseArgs($argv){

array_shift($argv);
$out = array();

foreach (
$argv as $arg){

// --foo --bar=baz
if (substr($arg,0,2) == '--'){
$eqPos = strpos($arg,'=');

// --foo
if ($eqPos === false){
$key = substr($arg,2);
$value = isset($out[$key]) ? $out[$key] : true;
$out[$key] = $value;
}
// --bar=baz
else {
$key = substr($arg,2,$eqPos-2);
$value = substr($arg,$eqPos+1);
$out[$key] = $value;
}
}
// -k=value -abc
else if (substr($arg,0,1) == '-'){

// -k=value
if (substr($arg,2,1) == '='){
$key = substr($arg,1,1);
$value = substr($arg,3);
$out[$key] = $value;
}
// -abc
else {
$chars = str_split(substr($arg,1));
foreach (
$chars as $char){
$key = $char;
$value = isset($out[$key]) ? $out[$key] : true;
$out[$key] = $value;
}
}
}
// plain-arg
else {
$value = $arg;
$out[] = $value;
}
}
return
$out;
}
}
?>
hmztsc at gmail dot com
4 年前
// 我想删除数组内部的第一个数组
// 但对我来说不起作用:array_shift();

$cargo_file =
数组
(
[0] => 数组
(
[0] => 国家
[1] => 国家代码
[2] => 城市
[3] => 城市其他语言
[4] => 邮政编码
[5] => 天数
)

[1] => 数组
(
[0] => 土耳其
[1] => TR
[2] => 伊斯坦布尔
[3] => 伊斯坦布尔
[4] => 34930
[5] => 9
)

)

$cargo_file = array_shift($cargo_file);

echo "<pre>";
print_r($cargo_file);
echo "</pre>";

// 结果之后

/*
数组
(
[0] => 国家
[1] => 国家代码
[2] => 城市
[3] => 城市其他语言
[4] => 邮政编码
[5] => 天数
)
*/

我开发了一个解决方案

function removeFirstArray($array){

$new_array = [];
foreach ($array as $key => $value) {
if($key > 0){
$new_array[] = $value;
}
}

return $new_array;
}

$cargo_file= removeFirstArray($cargo_file);

echo "<pre>";
print_r($cargo_file);
echo "</pre>";

数组
(
[0] => 数组
(
[0] => 土耳其
[1] => TR
[2] => 伊斯坦布尔
[3] => 伊斯坦布尔
[4] => 34930
[5] => 9
)

)
匿名用户
19 年前
<?php

//----------------------------------------------------------
// array_shift/array_unshift 的组合
// 极大地简化了我为生成相对路径而创建的一个函数。
// 在我找到它们之前,该算法非常混乱,包含多个
// if 测试、长度计算、嵌套循环等。
// 非常棒的函数。
//----------------------------------------------------------

function create_relative_path($inSourcePath, $inRefPath)
{
// 在斜杠处分割字符串
$s_parts = explode('/', $inSourcePath);
$r_parts = explode('/', $inRefPath);

// 删除第一个不相同部分之前的项目
while ($s_parts[0] === $r_parts[0])
{
array_shift($s_parts);
array_shift($r_parts);
}

// 为 $s_parts 的每个剩余项目向 $r_parts 添加通配符
// 项目
while ($s_parts[0])
{
array_unshift($r_parts, '..');
array_shift($s_parts);
}

return
implode('/', $r_parts);
}

//----------------------------------------------------------
// 示例:
// 给定源路径 $sp,生成 $rp 的相对位置。 $sp 可以使用
// $_SERVER['PHP_SELF'] 赋值,但在此示例中为硬编码。
//----------------------------------------------------------
$sp = '/WebServer/Documents/MyBigProject/php/project_script.php';
$rp = '/WebServer/Documents/MyLibraries/lib_script.php';

// 将它们插入函数中
$rel_path = create_relative_path($sp, $rp);

// 生成
'../../../MyLibraries/lib_script.php'

// 并可以像这样使用
include_once(create_relative_path($_SERVER['PHP_SELF'], $rp));
malima
2 年前
一个简单的基准测试(PHP 8.1.9 + macOS 12.4)

<?php

ini_set
('memory_limit', -1);

$times = 25_000;
$length = 256;
$arr = [];

$random = random_bytes(($times + $length) / 2);
$random = bin2hex($random);

// 基准测试 array_shift()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$shiftTimer = -hrtime(true);
for (
$i = 0; $i < $times; $i++) {
$value = array_shift($arr);
}
$shiftTimer += hrtime(true);

// 基准测试 array_reverse() + array_pop() + array_reverse()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$reverseTimer = -hrtime(true);
for (
$i = 0; $i < $times; $i++) {
$arr = array_reverse($arr);
$value = array_pop($arr);
$arr = array_reverse($arr);
}
$reverseTimer += hrtime(true);

// 基准测试 array_reverse() + array_pop()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$popTimer = -hrtime(true);
$arr = array_reverse($arr);
for (
$i = 0; $i < $times; $i++) {
$value = array_pop($arr);
}
$popTimer += hrtime(true);

// 基准测试 $arr[key()]+ unset(key())
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$keyTimer = -hrtime(true);
reset($arr);
for (
$i = 0; $i < $times; $i++) {
$key = key($arr);
$val = $arr[$key];
unset(
$arr[$key]);
}
$keyTimer += hrtime(true);

print_r([
'shift' => $shiftTimer / (10 ** 9),
'reverse' => $reverseTimer / (10 ** 9),
'pop' => $popTimer / (10 ** 9),
'key' => $keyTimer / (10 ** 9),
]);

?>

结果解读

在一个包含 25,000 个唯一项目的数组上,每个项目都是一个 256 字节的字符串

并且 key() + unset() 非常快。

array_shift() 慢约 400 倍

array_reverse() + array_pop() + array_reverse() 慢约 5,000 倍。

附注:我正在实现一个队列,因此我需要在 array_pop() 之后添加另一个 array_reverse(),这使得它在循环中变得极其缓慢。 array_reverse() + array_pop() 对我来说没有用,我只是为了检查它的性能而添加的。 它与 key() + unset() 一样快。
匿名
4 年前
示例中的“$stack”应该称为“$queue”。
wheberson dot com dot br at gmail dot com
5 年前
// 例 1:signedShiftArray (['A', 'B', 'C', 'D'], 2) -> ['C', 'D', 'A', 'B']
// 例 2:signedShiftArray (['A', 'B', 'C', 'D'], -3) -> ['B', 'C', 'D', 'A']
// 例 3:signedShiftArray (['A', 'B', 'C', 'D'], -7) -> ['B', 'C', 'D', 'A']

function signedShiftArray ($aItems, $aOffset)

{
if (empty ($aItems))
return [];
else if (empty ($aOffset))
return $aItems;
else {
$t= count ($aItems);
$n= $aOffset % $t;
$m= $aOffset > 0 ? $n : $t + $aOffset;
return array_merge(array_slice($aItems, $n), array_slice($aItems, 0, $m));
}
}
[email protected]
5 年前
有时,您不需要打乱数组,只需旋转它即可。我们可以使用以下代码轻松地向左旋转数组
<?php
$arr
[] = array_shift($arr);
?>
[email protected]
11 年前
行内赋值不会删除元素。

$first = array_shift( $arr = array( 0 => '1st', 2 => '2nd', 3 => '3rd') );
print_r( $first );
print_r( $arr );

输出
1st
数组
(
[0] => 1st
[2] => 2nd
[3] => 3rd
)
[email protected]
16 年前
// 通过 Saurabh Goyal 更改数组顺序
function change_array_order($table,$order)
{
// 初始化新表
$new_table = array();
foreach($order as $colname)
{
$new_table[$colname] = $table[$colname];
}
return $new_table;
}

如果数组值类似于:
$row = array('usr_id'=>'23','usr_name'=>'Saurabh', 'usr_surname'=>'Goyal','usr_firstname'=>'Saurabh');

// 您想更改顺序并仅显示特定字段
change_array_order($row,array('usr_name','usr_firstname',
'usr_surname'));

此致

Saurabh Goyal
http://sggoyal.blogspot.com
Ben
17 年前
[email protected],我认为这种方法效率更高。

<?php
function array_shorten($arr)
{
list(
$k) = array_keys($arr);
unset(
$arr[$k]);
return
$arr;
}
?>
[email protected]
17 年前
我需要从关联数组中删除第一组键值对。不得不编写此函数

function shortenArray($_arr)
{
$i=1;
$_shorter=array();
foreach ($_arr as $k => $v)
{
if ($i != 1)
{
$_shorter[$k] = $v;
}
$i++;
}
return $_shorter;
}
[email protected]
17 年前
如果您想遍历一个数组,使用 array_shift() 一次删除一个值,但也希望得到键,请尝试以下方法。

<?php

while($key = key($array))
{
$value = array_shift($array);
// 代码在此处
}

?>

它类似于 foreach,但每次都会从数组中删除值,因此最终数组会变为空。

<?php

// 下面的示例

$airports = array
(
"LGW" => "London Gatwick",
"LHR" => "London Heathrow",
"STN" => "London Stanstead"
);

echo
count($airports)." Airport in the array<br /><br />";

while(
$key = key($airports))
{
$value = array_shift($airports);
echo
$key." is ".$value."<br />";
}

echo
"<br />".count($airports)." Airport left in the array";

?>

示例输出

数组中有 3 个机场

LGW 是伦敦盖特威克机场
LHR 是伦敦希思罗机场
STN 是伦敦斯坦斯特德机场

数组中剩余 0 个机场
[email protected]
19 年前
我使用此函数来浏览数据库中的数组。例如数据
<?php
$data
= array(
array(
'row 1-cell 1','row 1-cell 2'),
array(
'row 2-cell 1','row 2-cell 2'),
array(
'row 3-cell 1','row 3-cell 2'),
);

while(
$row=array_shift($data)) {
echo
$row[0];
}
?>
输出
row 1-cell 1
row 2-cell 1
row 3-cell 1
James McGuigan
19 年前
while(array_shift()) 可用于在一个循环中处理多个数组和/或数据库结果。|| 会短路,并且只评估第一个语句,直到数据用完。

它有助于减少重复代码(规则是只写一次代码)。

请注意,每个 ($row = ) 语句都必须用 () 括起来,否则您将得到奇怪的结果。如果您使用两个 array_shift($array) 语句并忘记了 (),您将反复获得第一个数组的第一个元素,次数为 $array 的计数。

<?php

require_once('class.db.php');

$sql = "SELECT title FROM links";
$result = mysql_query($sql, $db->connection);

$defaults = array(
array(
'title' => 'None'),
array(
'title' => 'Unknown')
);

while ( (
$row = mysql_fetch_assoc($result))
|| (
$row = array_shift($defaults)))
{
echo
$row['title'] . "<br>";
}

?>

这将打印输出(取决于数据库内容)
Title1
Title2
Title3
...
None
Unknown
[email protected]
18 年前
我还没有深入研究,但如果您抱怨 PHP 5.0.5 中的更改导致您无法执行以下操作

<?php

$val
= array_shift(preg_split());

?>



<?php

$val
= array_shit(function_that_returns_array);

?>

那么您使用此函数的方式不正确。此函数的参数应该是指向变量的指针。然后它修改该变量并返回值。当您指定一个函数时,php 无法修改该函数的返回值。这应该是常识,但显然不是。

此外,在效率方面,您可能需要考虑使用其他函数,例如 reset,或者可能创建您自己的函数,如下所示

<?php

function first_element($array) {

return
reset($array);

}

?>

除非出于某种原因,您需要保存这需要花费的微秒数。

}
[email protected]
14 年前
如果您需要数组的第一个或最后一个条目,那么这可以帮助您。

<?php
function array_last_entry($arr){
if(!
is_array($arr))
return;

if(empty(
$arr))
return;

return
end($arr);
}

function
array_first_entry($arr){
if(!
is_array($arr))
return;

if(empty(
$arr))
return;

reset($arr);
return
current($arr);
}

$arr = array( '5' => 'five', '3' => 'three', '8' => 'eight',);

echo
'last entry: '.array_last_entry($arr).'<br>';

echo
'first entry: '.array_first_entry($arr).'<br>';

echo
'alternative output:<br>';

echo
'last entry: '.$arr[count($arr)-1];

echo
'<br>first entry: '.$arr[0];
?>

输出将如下所示
最后一个条目:eight


第一个条目:five
备选输出
最后一个条目
第一个条目

如您所见,如果您需要处理索引不连续的数组,这些函数可能非常有用。
C_Prevost (myob)
17 年前
不,它很好地证明了它删除了原始数组中的第一个元素,更新了键,并且它也返回了原始的第一个元素。
bmr (ediweb.org)
18 年前
如果数组具有非数值键,array_shift 将提取第一个元素(无论键是什么),并重新计算数值键(如果有)。例如:

$array = array("c" => "ccc", 0 => "aaa", "d" => "ddd", 5 => "bbb");
$first = array_shift($array);
echo '$first = ' . $first . ', $array = ' . var_export($array, true);

将显示

$first = ccc, $array = array ( 0 => 'aaa', 'd' => 'ddd', 1 => 'bbb', )

这意味着 array_shift 也适用于关联数组,并且如果键是非数值的,则保持键不变。
dmhouse (gmail.com)
17 年前
如果您想要一个非破坏性工作的 array_shift() 版本(即,一个易于使用的函数,用于获取数组的第一个元素而不修改数组),请尝试使用 reset()。
To Top