数组移除第一个元素但保留键名

21

我的数组看起来像这样:

$arValues = array( 345 => "jhdrfr", 534 => "jhdrffr", 673 => "jhrffr", 234 => "jfrhfr" );
如何删除数组的第一个元素,但保留数字键?因为array_shift会将我的整数键值更改为0、1、2、...
我尝试使用unset( $arValues[ $first ] ); reset( $arValues );来继续使用第二个元素(现在是第一个),但它返回了false
如何实现这个目标?
6个回答

22
reset( $a );
unset( $a[ key($a)]);

稍微更有用的版本:

// rewinds array's internal pointer to the first element
// and returns the value of the first array element. 
$value = reset( $a );

// returns the index element of the current array position
$key   = key( $a );

unset( $a[ $key ]);

功能:

// returns value
function array_shift_assoc( &$arr ){
  $val = reset( $arr );
  unset( $arr[ key( $arr ) ] );
  return $val; 
}

// returns [ key, value ]
function array_shift_assoc_kv( &$arr ){
  $val = reset( $arr );
  $key = key( $arr );
  $ret = array( $key => $val );
  unset( $arr[ $key ] );
  return $ret; 
}

3
因为我们特别想处理第一个元素。reset()将数组指针移动到第一个元素,key()返回该元素的索引。 - biziclop
使用后,我调用了 current($a);,它返回 false。出了什么问题? - Shlomo
我试图快速搜索一下 unset 后当前元素会是什么,但没有找到相关信息。"如果内部指针指向元素列表的末尾或数组为空,则 current() 返回 FALSE。" - biziclop
我用另一种方法实现了它:同时将索引移动到值中,所以我使用一个键和值的数组作为元素值,让 PHP 处理键 0、1、2...... 然后使用 array_shift 是可以的,因为它会改变键。但是还没有解决我的问题。 - Shlomo
在这种情况下,我不理解你的问题,也许需要编辑它或添加一些示例等。 - biziclop

15
// 1 is the index of the first object to get
// NULL to get everything until the end
// true to preserve keys
$arValues = array_slice($arValues, 1, NULL, true);

5
最佳答案在这里。不涉及指针,易于阅读。 - simPod
这绝对是一个易读的答案。不幸的是,它在性能方面明显较差,这可能会在大型数组上产生影响。我相信array_slice()的运行时间复杂度为O(N),额外的内存使用量也为O(N)(至少在垃圾回收释放被覆盖的旧数组副本之前是这样)。另一种使用key()和unset()的解决方案将对两者都是O(1)。将其放入名为"array_pop()"的函数中,您可以获得性能和可读性。 - Daniel

7

当我需要做这件事时,我会使用以下方法:

unset($a[array_key_first($a)]);

array_key_first()函数是在2018年底通过PHP 7.3引入/可用的。对于我的使用情况,我不需要处理指针,但仍然可以在需要时运行reset($a)。我没有看到任何最近的答案,所以我想加上这个。


2
做得好,使用当前/现代功能填补了这个空缺。我希望更多的人像你一样发表有价值的回复。另外,我也很高兴看到你的回答正在得到UV的支持--这是SO能够“正常运作”的罕见迹象。 - mickmackusa
文档中的Polyfill:https://www.php.net/manual/en/function.array-key-first.php#refsect1-function.array-key-first-notes - biziclop

1
function array_shift_associative(&$arr){
    reset($arr);
    $return = array(key($arr)=>current($arr));
    unset($arr[key($arr)]);
    return $return; 
}

这个函数使用biziclop的方法,但返回一个key=>value对。

0

我的解决方案与@PhilF的类似,但兼容旧版本的PHP - 对于那些需要编写与PHP版本早于PHP 7.3兼容的代码的罕见情况。

如果$myArray看起来像这样:

[
  345 => "jhdrfr",
  534 => "jhdrffr",
  673 => "jhrffr",
  234 => "jfrhfr"
]

那么array_keys($myArray)将会是这样的:

[
  345,
  534,
  673,
  234
]

array_keys($myArray)[0]将会是:

345

因此:

unset($myArray[array_keys($myArray)[0]]);

将删除第一个元素,而不重置键,结果为:

[
  534 => "jhdrffr",
  673 => "jhrffr",
  234 => "jfrhfr"
]

1
这是与被接受的答案相同的方法,但使用 array_keys($a)[0] 而不是 reset($a); key($a); 对。由于该问题是在2013年提出的,根据定义,大多数答案在PHP 5中都可以正常工作。 - miken32
感谢确认,@miken32。当我注意到array_shift()在我的脚本中重新索引数组时,我开始寻找一个参数来防止这种情况发生。在搜索网络时,没有在任何地方读到它,上面的解决方案出现在我脑海中。经过成功测试后,我想检查Stack Overflow是否已经存档了这个解决方案。它没有,所以我添加了它。我的意图不是替换已接受的答案,而是增加可能用于解决这个特定问题的方法数量。 - Rounin
1
好主意,但对于大型数组来说效率不高:它必须构建一个包含所有键的新数组,然后立即将其丢弃。文档中有一个很好的 polyfill:https://www.php.net/manual/en/function.array-key-first.php#refsect1-function.array-key-first-notes - biziclop

0

这对我来说很好用...

$array = array('1','2','3','4');

reset($array);
$key = key($array);
$value = $array[$key];
unset($array[$key]);

var_dump($key, $value, $array, current($array));

输出:

int(0) 
string(1) "1" 
array(3) { [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" }
string(1) "2"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接