从PHP关联数组中弹出键和值

25

在PHP中,假设有一个关联数组S,我需要检索并提取出其中的第一个元素,包括其键和值。

我会使用

value1=array_pop(S);

但是它只给我值。

我可以使用

K=array_keys(S);
key1=array_pop(K);
value1=array_pop(S);

但它很复杂,因为需要有两个相同数据的副本。这很令人困惑,因为该数组本身是一个数组中的元素。一定有更加优雅的方法来提取读取键/值对。


1
你想要移动(第一个元素)还是弹出(最后一个元素)? - hakre
5个回答

42
// first
$value = reset($arr);
$key = key($arr);

按照顺序查看reset()PHP手册key()PHP手册
unset($arr[$key]); # in case you want to remove it.

然而,array_pop()PHP手册是用于操作最后一个元素的。
// last
$value = end($arr);
$key = key($arr);
unset($arr[$key]); # in case you want to remove it.

查看end()PHP手册

为了好玩:

[$value, $key] = [reset($arr), key($arr)]; // first
[$value, $key] = [end($arr), key($arr)]; // last

(PHP 7.1+)

或者

list($value, $key) = array(reset($arr), key($arr)); // first
list($value, $key) = array(end($arr), key($arr)); // last

(PHP 4.3+)

或者

extract(array('value' => reset($arr), 'key' => key($arr))); // first
extract(array('value' => end($arr), 'key' => key($arr))); // last

(PHP 4.3+; 注意:extract() 正在使用!)

或者

// first
reset($arr);
list($key, $value) = each($arr);


// last
end($arr);
list($key, $value) = each($arr);

(注意:自 PHP 7.2.0 起,each() 函数已被弃用,并在 PHP 8.0.0 中移除)
或者你喜欢的任何风格 ;)
处理空数组
到目前为止,处理空数组一直是个问题。因此需要检查是否有最后(第一个)元素,如果没有,则将 $key 设置为 null(因为 null 不能作为数组键):
// first
for ($key = null, $value = null; false !== $_ = reset($arr);)
{
    $value = $_;
    unset($arr[$key = key($arr)]);
    break;
}
unset($_);

// last
for ($key = null, $value = null; false !== $_ = end($arr);)
{
    $value = $_;
    unset($arr[$key = key($arr)]);
    break;
}
unset($_);

这将为一个填充的数组提供,例如 $arr = array('first' => '1st', 'last' => '2nd.');:
string(4) "2nd." # value
string(4) "last" # key
array(1) { # leftover array
  ["first"]=>
  string(3) "1st"
}

一个空数组:
bool(false) # value
NULL # key
array(0) { # leftover array
}

害怕使用unset()吗?
如果你不相信unset()能够提供你所需的性能(尽管我认为这并不是真正的问题,虽然我没有运行任何指标),你也可以使用本地的array_pop()实现(但我真的认为作为语言结构的unset()可能会更快):
// first
reset($arr);
$key = key($arr);
$value = array_pop($arr);


// last
end($arr);
$key = key($arr);
$value = array_pop($arr);

谢谢。我对 unset($arr[$key]); 不太满意。它看起来需要系统再次遍历数组以找到实际值。 - Pietro Speroni
2
在PHP中,数组是哈希表。这是一种查找操作,而不是遍历整个数组的搜索,因此速度很快。 - hakre
是的,我也喜欢它。如果你需要处理空数组,那么对于一个紧凑的形式来说,它会变得有点棘手,所以为了好玩,你可以找到另一个编辑。 - hakre
这个解决方案是针对 array_shift,而不是 array_pop!使用 $value = end($arr); 而不是 $value = reset($arr); 来回答这个问题! - Alex Barker
@AlexBarker:答案说array_pop是用于最后一个元素,这应该强调一下OP可能存在的混淆,因为在伪代码/示例代码中有array_pop(),但在句子中使用了“[...]我需要检索和提取第一个元素,包括值和键。”-请参见我的原始评论 - hakre
显示剩余2条评论

7

array_slice

$arr = array('k1' => 'v1', 'k2' => 'v2', 'k3' => 'v3');

$a = array_slice($arr, 0, 1);
var_dump($a);

$arr = array_slice($arr, 1);
var_dump($arr);


array(1) {
  ["k1"]=>
  string(2) "v1"
}
array(2) {
  ["k2"]=>
  string(2) "v2"
  ["k3"]=>
  string(2) "v3"
}

1
array_slice() 是一个很好的想法。根据要对键和值做什么操作,可以使用以下代码:list($key, $value) = array_slice($arr, 0, 1); - KingCrunch
array_slice() 速度相对较慢,不是吗?我的意思是这是一个很好的函数,但就弹出数组末尾而言... - hakre
array_slice函数如果将$preserve_keys设置为true,则会保留原有的键名。 - shengbin_xu

6
$value = reset($array);
$key = key($array);

编辑:Hakre刚刚比我快了一步 :-)


4
list($value, $key) = array(reset($s), key($s));
array_shift($s); // or just unset($s[$key]);

当然,您可以将第一个语句分成两个单独的语句。

$key = key($s); $value = array_shift($s); 这样行吗? - Pietro Speroni
1
是的,这就是我所说的“你可以将其拆分” :) (只要数组指针指向第一个元素(这就是reset()的作用), - KingCrunch
不幸的是,每次我使用 array_shift 时,数组都会变为空。无论我之前是否使用了 reset。我认为我将使用上面建议的 unset。 - Pietro Speroni

0

我在类似的情况下做了以下事情:

$last_index = count($test_array)-1;
if($last_index >= 0) {
    $last_key = array_keys($test_array)[$last_index];
    foreach($test_array as $k => $v) {
        if($k == $last_key)
            echo "last: ";
        echo $k . '=' . $v . PHP_EOL;
    }
}

尽管我最终使用的解决方案是 while 循环(我实际上不需要保留键),但我基本上是试图将数组元素放在 pdf 的一个区域上,通过将多个元素放在同一行上来实现。我使用了 array_chunk() 将数组分成每个子数组 5 个或更少的子数组,然后使用 while(count($chunks) > 0) {} 移动结果数组。这篇文章中的一些解决方案也可以类似地在 while 循环中移动/取消设置数组元素,直到数组为空。


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