array_shift

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

array_shift从数组开头移出元素

描述

array_shift(array &$array): mixed

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

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

参数

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

参见

添加注释

用户贡献注释 31 注释

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

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

使用直接索引引用,即 array_test[$i],速度很快,但破坏性操作的直接索引引用 + unset 与 array_reverse 和 array_pop 的速度大致相同。它还需要顺序数字键。
62
elad dot yosifon at gmail dot com
11 年前
注意
array_pop() 的复杂度为 O(1)。
array_shift() 的复杂度为 O(n)。
array_shift() 需要对数组进行重新索引过程,因此它必须遍历所有元素并对其进行索引。
25
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
)
7
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

?>
5
chris {at} w3style {dot} co {dot} uk
15 年前
如前所述,在 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');
}

}

?>
4
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"
}
*/
?>

希望这对大家有所帮助!
2
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
5
Traps
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

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

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

<?php

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

?>
1
patrick at pwfisher dot com
14 年前
这里有一个实用程序函数来解析命令行参数。

<?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;
}
}
?>
2
hmztsc at gmail dot com
4 年前
// 我想删除第一个数组内的数组
// 但是对我来说不起作用: array_shift();

$cargo_file =
数组
(
[0] => Array
(
[0] => Country
[1] => CountryCode
[2] => City
[3] => CityOtherLanguage
[4] => PostCode
[5] => Days
)

[1] => Array
(
[0] => Turkey
[1] => TR
[2] => Istanbul
[3] => Istanbul
[4] => 34930
[5] => 9
)

)

$cargo_file = array_shift($cargo_file);

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

// 结果之后

/*
数组
(
[0] => Country
[1] => CountryCode
[2] => City
[3] => CityOtherLanguage
[4] => PostCode
[5] => Days
)
*/

我开发了一个解决方案

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] => Array
(
[0] => Turkey
[1] => TR
[2] => Istanbul
[3] => Istanbul
[4] => 34930
[5] => 9
)

)
1
Anonymous
18 年前
<?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));
0
malima
1 年前
一个简单的基准测试 (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() 一样快。
1
匿名
4 年前
示例中的 “$stack” 应该称为 “$queue”。
1
wheberson dot com dot br at gmail dot com
4 年前
// 例子 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));
}
}
0
vasiliauskas dot agnius at gmail dot com
5 年前
有时你不需要打乱数组,只需要旋转它。 我们可以用以下代码轻松地将数组向左旋转
<?php
$arr
[] = array_shift($arr);
?>
0
drum_inc at yahoo dot com
10 年前
行内的赋值不会删除元素。

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

输出
1st
数组
(
[0] => 1st
[2] => 2nd
[3] => 3rd
)
0
sggoyal at gmail dot com
15 年前
// 由 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
0
Ben
16 年前
baughmankr at appstate dot edu,我认为这样更有效率。

<?php
function array_shorten($arr)
{
list(
$k) = array_keys($arr);
unset(
$arr[$k]);
return
$arr;
}
?>
0
baughmankr at appstate dot edu
16 年前
我需要从一个关联数组中删除第一组键值对。 不得不想出这个函数

function shortenArray($_arr)
{
$i=1;
$_shorter=array();
foreach ($_arr as $k => $v)
{
if ($i != 1)
{
$_shorter[$k] = $v;
}
$i++;
}
return $_shorter;
}
0
richard at happymango dot me dot uk
17 年前
如果你想遍历一个数组,一次使用 array_shift() 删除一个值,并且还想获得键,试试这个。

<?php

while($key = key($array))
{
$value = array_shift($array);
// 这里写代码
}

?>

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

<?php

//以下为示例

$airports = array
(
"LGW" => "伦敦盖特威克",
"LHR" => "伦敦希思罗",
"STN" => "伦敦斯坦斯特德"
);

echo
count($airports)." 个机场在数组中<br /><br />";

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

echo
"<br />".count($airports)." 个机场剩余在数组中";

?>

示例输出

3 个机场在数组中

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

0 个机场剩余在数组中
0
lukasz dot dywicki DEL at gmail dot com
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
0
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
-1
alreece45 at yahoo dot com
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);

}

?>

当然,除非你出于某种原因需要保存它所花费的微秒数。

}
-3
ar at xonix dot ch
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];
?>

输出将如下所示
last entry: eight
first entry: five
alternative output
last entry
first entry

如你所见,如果你必须处理具有非连续索引的数组,这些函数可能非常有用。
-3
C_Prevost at myob
17 年前
不,它很好地证明了它删除了原始数组中的第一个元素,更新了键,并且它也返回了原始的第一个元素。
-3
bmr at ediweb dot 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 也适用于关联数组,如果键是非数值的,则保持键不变。
-6
info at chihoang dot de
13 年前
这在二维数组中不起作用。对于二维数组,我这样做

<?php
$backup
= $arr;
$first = array_shift ( $backup );
?>
-5
dmhouse at gmail dot com
17 年前
如果你想要一个非破坏性的 array_shift() 版本(即,一个简单的函数来获取数组的第一个元素,而不会修改数组),请尝试使用 reset()。
-6
Maikel
16 年前
回应 nando_f at nothingsimple dot com

示例是正确的,array_shift 对第一个元素进行了 unset 操作,因为参数是按引用传递的
To Top