在不改变其他数组键的情况下向数组开头添加一个元素

26

如何在 PHP 中将一个元素添加到数组的开头而不改变数组键值?


那该怎么做?如果你有一个键为0的项目呢? - Dominic Rodger
3
你能给出一个数组的例子来说明需要什么样的输入和输出吗? - sushil bharwani
9个回答

80
为了避免数值键被重新索引,您可以简单地将数组相加。

不要这样写:

array_unshift($arr1, $arr2)

尝试:

$arr1 = $arr2 + $arr1;

2
我一直避免使用这种方式添加数组,而更喜欢使用array_merge,但现在我有一个正当的理由来使用它。谢谢! - Benjam

24
如果您使用自定义(例如文字)键,则可以使用array_unshift()来处理。
如果您使用自动生成的(数字)键,该怎么办?将'-1'作为新的第一个键吗?
编辑: 感谢JasonS指出这个答案中的错误。 无论是自动生成的还是自定义的任何数字键都将被array_unshift()重新索引,如果是数字的话,它将被打乱。有关详细信息,请参见上面的文档链接。

不,因为如果索引代表表中的ID,则永远不会有零索引,因此这对于这些情况可以正常工作。 - Claire
@Nicola 对不起 - 我不明白你想告诉我什么。 - Martin Hennings
我的意思是,如果你从数据库返回行,并且数组的键是行ID,则数组永远不会有0键。因此,在这种情况下,索引不可能为-1。 - Claire
任何数字索引数组都将被重新索引以从零开始计数,正如您链接的array_unshift()文档中所解释的那样。您的示例具有数字键,因此如果使用array_unshift(),它将被重新索引。 - Jason S
我试图使用你的原始示例编辑你的答案,但它被(其他人)拒绝了。可能他们没有注意到我正在使用你的原始示例。因此,我将其作为(缩写)评论发布。要从整数索引数组 $a 中取出三个项目,并将它们移到数组的前面(使用你的原始示例),你可以这样做:$a = array_slice($a, -3, null, true) + $a; - Jason S
自从我上次评论以来,我已经将我对您答案所做的修改作为我的答案添加了进去,因为这是审阅者建议我采取的措施。不过,我认为SO的精神在于编辑和改进答案,而不是添加多个冗余的答案。请原谅我。 - Jason S

7
使用array_unshift()函数。(如上所述,它会保留字符串键,但不保留数值键。)

1
所有数字数组键将被修改为从零开始计数,而文字键不会被更改。 - Dominic Rodger

4

试试这个:

function array_insert(&$array, $insert, $position = -1) {
        $position = ($position == -1) ? (count($array)) : $position ;

        if($position != (count($array))) {
            $ta = $array;

            for($i = $position; $i < (count($array)); $i++) {
                if(!isset($array[$i])) {
                    die(print_r($array, 1)."\r\nInvalid array: All keys must be numerical and in sequence.");
                }

                $tmp[$i+1] = $array[$i];
                unset($ta[$i]);
            }

            $ta[$position] = $insert;
            $array = $ta + $tmp;
            //print_r($array);
        } else {
            $array[$position] = $insert;
        }

        //ksort($array);
        return true;
    }

2

我添加了自己(冗余的)答案,因为我试图编辑Martin的答案,使用他的原始示例,但被其他人(不是Martin)拒绝了。也许他们没有审查他的答案历史,因为我正在使用他的原始示例数组和问题。这是我的被拒绝的编辑。

Kevin Wentworth的答案是正确的。扩展该答案,使用Martin的答案中的原始示例,如果您有一个数组

$a = [1 => a, 2 => b, 5 => e, 6 => f, 8 => h, 9 => i];

如果你想将最后三个项目添加到同一数组的开头,那么可以执行以下操作。

$a = array_slice($a, -3, null, true) + $a;

结果数组为:
 array (6 => 'f', 8 => 'h', 9 => 'i', 1 => 'a', 2 => 'b', 5 => 'e',)

注意事项

array_slice函数的true参数会保留数字键(array_unshift没有此参数)。

尽管array_slice不会从原始数组中删除任何内容,但由于数组上的+运算符的行为,最后三个项目被取消了。

来自+数组运算符文档:

+运算符返回右侧附加到左侧的数组;对于两个数组中都存在的键,将使用左侧数组中的元素,并忽略右侧数组中的匹配元素。


2

如果您想在循环中使用此函数,请注意以下事项:

http://jp2.php.net/manual/en/function.array-unshift.php所述:

array_unshift()将所传递的元素前置到数组的前面。请注意,元素列表会作为一个整体前置,因此前置的元素顺序不会改变。所有数字数组键都将从零开始计数,而文字键则不会被修改。

为了让您了解其速度慢的情况,我们编写了一些基于http://pastebin.com/Jad5TjsQ的基准测试代码,并且下面是结果:

mt@wizcorp-dev2:~/dev/test$ for d in arrayFillBrackets.php arrayFillPush.php arrayFillUnshift.php arrayFillPushReverse.php ; do cat $d; php $d; done
<?php
require "benchmark.php";

function ArrayFillBrackets()
{
    $result = array();
    for($i = 0; $i < 10000; $i++) $result[] = $i;
    return $result;
}

$result = array();
$result[10]['ArrayFillBrackets'] = Benchmark('ArrayFillBrackets', null, 10);

!!! Benchmarking function ArrayFillBrackets for 10 iteration (args:null)...
===================
Results:
===================
time total:     0.02686286
time min:       0.00198293
time max:       0.0058589
time avg:       0.002686286
memory total:       0
memory min:     0
memory max:     0
memory avg:     0
<?php
require "benchmark.php";

function ArrayFillPush()
{
    $result = array();
    for($i = 0; $i < 10000; $i++) array_push($result, $i);
    return $result;
}

$result = array();
$result[10]['ArrayFillPush'] = Benchmark('ArrayFillPush', null, 10);

!!! Benchmarking function ArrayFillPush for 10 iteration (args:null)...
===================
Results:
===================
time total:     0.03958679
time min:       0.003757
time max:       0.00485086
time avg:       0.003958679
memory total:       0
memory min:     0
memory max:     0
memory avg:     0
<?php
require "benchmark.php";

function ArrayFillUnshift()
{
    $result = array();
    for($i = 0; $i < 10000; $i++) array_unshift($result, $i);
    return $result;
}

$result = array();
$result[1]['ArrayFillUnshift'] = Benchmark('ArrayFillUnshift', null, 1);

!!! Benchmarking function ArrayFillUnshift for 1 iteration (args:null)...
===================
Results:
===================
time total:     3.62487912
time min:       3.62487912
time max:       3.62487912
time avg:       3.62487912
memory total:       0
memory min:     0
memory max:     0
memory avg:     0
<?php
require "benchmark.php";

function ArrayFillPushReverse()
{
    $result = array();
    for($i = 0; $i < 10000; $i++) array_push($result, $i);
    return array_reverse($result);
}

$result = array();
$result[10]['ArrayFillPushReverse'] = Benchmark('ArrayFillPushReverse', null, 10);

!!! Benchmarking function ArrayFillPushReverse for 10 iteration (args:null)...
===================
Results:
===================
time total:     0.05071593
time min:       0.00475311
time max:       0.00560999
time avg:       0.005071593
memory total:       108
memory min:     0
memory max:     24
memory avg:     10.8
mt@wizcorp-dev2:~/dev/test$

请注意,所有测试都是10 * 10,000,除了运行1 * 10,000的array_unshift(等得有点累了)...所以再次提醒,在迭代中不要使用array_shift,因为仅反转数组一次几乎没有成本。

0

0
使用 array_unshift() 函数;这将帮助你添加元素。

1
array_unshift() 会重新索引数字键。 - Narf

0

嗯,如果你正在做我所做的事情,并且使用从数据库中索引为 DB 表 ids 的结果创建选择表单,但是想要在数组中添加一个索引为 0 的 "任何...",只需首先创建包含该项的数组变量,然后从数据库中填充剩余的值即可。无需在数据库调用后进行 unshift 或排序。


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