545

How can I insert a new item into an array on any position, for example in the middle of array?

MC Emperor
  • 17,266
  • 13
  • 70
  • 106
kusanagi
  • 13,070
  • 19
  • 78
  • 106
  • 4
    Possible duplicate of [How to insert element into arrays at specific position?](https://stackoverflow.com/questions/3353745/how-to-insert-element-into-arrays-at-specific-position) – Kashyap Kotak Jun 22 '18 at 15:08

22 Answers22

1029

You may find this a little more intuitive. It only requires one function call to array_splice:

$original = array( 'a', 'b', 'c', 'd', 'e' );
$inserted = array( 'x' ); // not necessarily an array, see manual quote

array_splice( $original, 3, 0, $inserted ); // splice in at position 3
// $original is now a b c x d e

If replacement is just one element it is not necessary to put array() around it, unless the element is an array itself, an object or NULL.

Félix Gagnon-Grenier
  • 7,344
  • 10
  • 45
  • 58
jay.lee
  • 17,466
  • 7
  • 36
  • 38
  • 43
    It's odd that such a basic functionality is actually sort of hidden, in that the main purpose of this function as described in the documentation is something different (replace stuff in arrays). Yes, it is pointed out in the arguments section, but if you are just scanning function descriptions to find what to use to insert in arrays you would have never found it. – Mahn Jun 21 '12 at 00:26
  • 30
    Just saying that this will not preserve keys in the `$inserted` array. – mauris Jun 27 '12 at 06:58
  • 6
    Also in PHP manual, example #1: http://php.net/manual/en/function.array-splice.php – marcovtwout Dec 03 '12 at 13:16
  • 3
    @JacerOmri it is totally right, both statements are valid. You can pass a value of any type, but it might not behave the same for an array, an object, or null. For scalars, type-casting `(array)$scalar` is equivalent to `array($scalar)`, but for an array, an object, or null, it will be ignored (array), convert to an array (object), or become an empty array (null) - see http://php.net/manual/en/language.types.array.php#language.types.array.casting – Lukas Nov 27 '14 at 07:49
  • 3
    @SunilPachlangia, adelval and others: with multi-dimensional arrays you need to wrap the replacement in an array, it's documented. I still brought the note here so people stop doing the mistake. – Félix Gagnon-Grenier Jul 17 '18 at 16:09
  • 2
    @SunilPachlangia For a multidimensional array, this function allowed me to insert an array at a specified position: https://gist.github.com/wpscholar/0deadce1bbfa4adb4e4c It seems similar to other functions on this page, but I found it easier to understand. – Ryan May 07 '19 at 22:15
52

A function that can insert at both integer and string positions:

/**
 * @param array      $array
 * @param int|string $position
 * @param mixed      $insert
 */
function array_insert(&$array, $position, $insert)
{
    if (is_int($position)) {
        array_splice($array, $position, 0, $insert);
    } else {
        $pos   = array_search($position, array_keys($array));
        $array = array_merge(
            array_slice($array, 0, $pos),
            $insert,
            array_slice($array, $pos)
        );
    }
}

Integer usage:

$arr = ["one", "two", "three"];
array_insert(
    $arr,
    1,
    "one-half"
);
// ->
array (
  0 => 'one',
  1 => 'one-half',
  2 => 'two',
  3 => 'three',
)

String Usage:

$arr = [
    "name"  => [
        "type"      => "string",
        "maxlength" => "30",
    ],
    "email" => [
        "type"      => "email",
        "maxlength" => "150",
    ],
];

array_insert(
    $arr,
    "email",
    [
        "phone" => [
            "type"   => "string",
            "format" => "phone",
        ],
    ]
);
// ->
array (
  'name' =>
  array (
    'type' => 'string',
    'maxlength' => '30',
  ),
  'phone' =>
  array (
    'type' => 'string',
    'format' => 'phone',
  ),
  'email' =>
  array (
    'type' => 'email',
    'maxlength' => '150',
  ),
)
Halil Özgür
  • 14,749
  • 4
  • 45
  • 55
  • 2
    The `array_splice()` loses the keys, whereas `array_merge()` does not. So the results of the first function can be very surprising... Especially because if you have two elements with the same key, only the value of the last one is kept... – Alexis Wilke Nov 20 '16 at 02:26
34
$a = array(1, 2, 3, 4);
$b = array_merge(array_slice($a, 0, 2), array(5), array_slice($a, 2));
// $b = array(1, 2, 5, 3, 4)
George Garchagudashvili
  • 6,657
  • 12
  • 39
  • 53
Amber
  • 446,318
  • 77
  • 595
  • 531
6

This way you can insert arrays:

function array_insert(&$array, $value, $index)
{
    return $array = array_merge(array_splice($array, max(0, $index - 1)), array($value), $array);
}
Aleksandr Makov
  • 2,564
  • 2
  • 29
  • 59
6

There is no native PHP function (that I am aware of) that can do exactly what you requested.

I've written 2 methods that I believe are fit for purpose:

function insertBefore($input, $index, $element) {
    if (!array_key_exists($index, $input)) {
        throw new Exception("Index not found");
    }
    $tmpArray = array();
    $originalIndex = 0;
    foreach ($input as $key => $value) {
        if ($key === $index) {
            $tmpArray[] = $element;
            break;
        }
        $tmpArray[$key] = $value;
        $originalIndex++;
    }
    array_splice($input, 0, $originalIndex, $tmpArray);
    return $input;
}

function insertAfter($input, $index, $element) {
    if (!array_key_exists($index, $input)) {
        throw new Exception("Index not found");
    }
    $tmpArray = array();
    $originalIndex = 0;
    foreach ($input as $key => $value) {
        $tmpArray[$key] = $value;
        $originalIndex++;
        if ($key === $index) {
            $tmpArray[] = $element;
            break;
        }
    }
    array_splice($input, 0, $originalIndex, $tmpArray);
    return $input;
}

While faster and probably more memory efficient, this is only really suitable where it is not necessary to maintain the keys of the array.

If you do need to maintain keys, the following would be more suitable;

function insertBefore($input, $index, $newKey, $element) {
    if (!array_key_exists($index, $input)) {
        throw new Exception("Index not found");
    }
    $tmpArray = array();
    foreach ($input as $key => $value) {
        if ($key === $index) {
            $tmpArray[$newKey] = $element;
        }
        $tmpArray[$key] = $value;
    }
    return $input;
}

function insertAfter($input, $index, $newKey, $element) {
    if (!array_key_exists($index, $input)) {
        throw new Exception("Index not found");
    }
    $tmpArray = array();
    foreach ($input as $key => $value) {
        $tmpArray[$key] = $value;
        if ($key === $index) {
            $tmpArray[$newKey] = $element;
        }
    }
    return $tmpArray;
}
A Boy Named Su
  • 160
  • 2
  • 7
  • 2
    This works fine. However, in the second example, in your function `insertBefore()`, you should return `$tmpArray` instead of `$input`. – Christoph Fischer Oct 12 '17 at 13:20
6

If you want to keep the keys of the initial array and also add an array that has keys, then use the function below:

function insertArrayAtPosition( $array, $insert, $position ) {
    /*
    $array : The initial array i want to modify
    $insert : the new array i want to add, eg array('key' => 'value') or array('value')
    $position : the position where the new array will be inserted into. Please mind that arrays start at 0
    */
    return array_slice($array, 0, $position, TRUE) + $insert + array_slice($array, $position, NULL, TRUE);
}

Call example:

$array = insertArrayAtPosition($array, array('key' => 'Value'), 3);
Mayra M
  • 526
  • 4
  • 5
5
function insert(&$arr, $value, $index){       
    $lengh = count($arr);
    if($index<0||$index>$lengh)
        return;

    for($i=$lengh; $i>$index; $i--){
        $arr[$i] = $arr[$i-1];
    }

    $arr[$index] = $value;
}
nhahtdh
  • 52,949
  • 15
  • 113
  • 149
henry wong
  • 51
  • 1
  • 1
5

Based on @Halil great answer, here is simple function how to insert new element after a specific key, while preserving integer keys:

private function arrayInsertAfterKey($array, $afterKey, $key, $value){
    $pos   = array_search($afterKey, array_keys($array));

    return array_merge(
        array_slice($array, 0, $pos, $preserve_keys = true),
        array($key=>$value),
        array_slice($array, $pos, $preserve_keys = true)
    );
} 
d.raev
  • 8,090
  • 8
  • 51
  • 72
4

This is what worked for me for the associative array:

/*
 * Inserts a new key/value after the key in the array.
 *
 * @param $key
 *   The key to insert after.
 * @param $array
 *   An array to insert in to.
 * @param $new_key
 *   The key to insert.
 * @param $new_value
 *   An value to insert.
 *
 * @return
 *   The new array if the key exists, FALSE otherwise.
 *
 * @see array_insert_before()
 */
function array_insert_after($key, array &$array, $new_key, $new_value) {
  if (array_key_exists($key, $array)) {
    $new = array();
    foreach ($array as $k => $value) {
      $new[$k] = $value;
      if ($k === $key) {
        $new[$new_key] = $new_value;
      }
    }
    return $new;
  }
  return FALSE;
}

The function source - this blog post. There's also handy function to insert BEFORE specific key.

Oksana Romaniv
  • 1,342
  • 12
  • 18
3

This is also a working solution:

function array_insert(&$array,$element,$position=null) {
  if (count($array) == 0) {
    $array[] = $element;
  }
  elseif (is_numeric($position) && $position < 0) {
    if((count($array)+position) < 0) {
      $array = array_insert($array,$element,0);
    }
    else {
      $array[count($array)+$position] = $element;
    }
  }
  elseif (is_numeric($position) && isset($array[$position])) {
    $part1 = array_slice($array,0,$position,true);
    $part2 = array_slice($array,$position,null,true);
    $array = array_merge($part1,array($position=>$element),$part2);
    foreach($array as $key=>$item) {
      if (is_null($item)) {
        unset($array[$key]);
      }
    }
  }
  elseif (is_null($position)) {
    $array[] = $element;
  }  
  elseif (!isset($array[$position])) {
    $array[$position] = $element;
  }
  $array = array_merge($array);
  return $array;
}

credits go to: http://binarykitten.com/php/52-php-insert-element-and-shift.html

Mike Doh
  • 51
  • 3
3

if unsure, then DONT USE THESE:

$arr1 = $arr1 + $arr2;

OR

$arr1 += $arr2;

because with + original array will be overwritten. (see source)

Community
  • 1
  • 1
T.Todua
  • 44,747
  • 17
  • 195
  • 185
3

Solution by jay.lee is perfect. In case you want to add item(s) to a multidimensional array, first add a single dimensional array and then replace it afterwards.

$original = (
[0] => Array
    (
        [title] => Speed
        [width] => 14
    )

[1] => Array
    (
        [title] => Date
        [width] => 18
    )

[2] => Array
    (
        [title] => Pineapple
        [width] => 30
     )
)

Adding an item in same format to this array will add all new array indexes as items instead of just item.

$new = array(
    'title' => 'Time',
    'width' => 10
);
array_splice($original,1,0,array('random_string')); // can be more items
$original[1] = $new;  // replaced with actual item

Note: Adding items directly to a multidimensional array with array_splice will add all its indexes as items instead of just that item.

Abdul Mannan
  • 943
  • 9
  • 16
3

You can use this

foreach ($array as $key => $value) 
{
    if($key==1)
    {
        $new_array[]=$other_array;
    }   
    $new_array[]=$value;    
}
Devil
  • 284
  • 2
  • 12
2

Hint for adding an element at the beginning of an array:

$a = array('first', 'second');
$a[-1] = 'i am the new first element';

then:

foreach($a as $aelem)
    echo $a . ' ';
//returns first, second, i am...

but:

for ($i = -1; $i < count($a)-1; $i++)
     echo $a . ' ';
//returns i am as 1st element
forsberg
  • 1,309
  • 16
  • 23
  • 14
    Hint for adding an element at the beginning: `array_unshift($a,'i am the new first element');` –  Jul 04 '13 at 08:31
2

Try this one:

$colors = array('red', 'blue', 'yellow');

$colors = insertElementToArray($colors, 'green', 2);


function insertElementToArray($arr = array(), $element = null, $index = 0)
{
    if ($element == null) {
        return $arr;
    }

    $arrLength = count($arr);
    $j = $arrLength - 1;

    while ($j >= $index) {
        $arr[$j+1] = $arr[$j];
        $j--;
    }

    $arr[$index] = $element;

    return $arr;
}
GitaarLAB
  • 13,494
  • 9
  • 51
  • 74
Max
  • 21
  • 1
2
function array_insert($array, $position, $insert) {
    if ($position > 0) {
        if ($position == 1) {
            array_unshift($array, array());
        } else {
            $position = $position - 1;
            array_splice($array, $position, 0, array(
                ''
            ));
        }
        $array[$position] = $insert;
    }

    return $array;
}

Call example:

$array = array_insert($array, 1, ['123', 'abc']);
xayer
  • 143
  • 8
1

Normally, with scalar values:

$elements = array('foo', ...);
array_splice($array, $position, $length, $elements);

To insert a single array element into your array don't forget to wrap the array in an array (as it was a scalar value!):

$element = array('key1'=>'value1');
$elements = array($element);
array_splice($array, $position, $length, $elements);

otherwise all the keys of the array will be added piece by piece.

mark
  • 21,478
  • 3
  • 46
  • 67
0

For inserting elements into an array with string keys you can do something like this:

/* insert an element after given array key
 * $src = array()  array to work with
 * $ins = array() to insert in key=>array format
 * $pos = key that $ins will be inserted after
 */ 
function array_insert_string_keys($src,$ins,$pos) {

    $counter=1;
    foreach($src as $key=>$s){
        if($key==$pos){
            break;
        }
        $counter++;
    } 

    $array_head = array_slice($src,0,$counter);
    $array_tail = array_slice($src,$counter);

    $src = array_merge($array_head, $ins);
    $src = array_merge($src, $array_tail);

    return($src); 
} 
0

This can be done with array_splice however, array_splice fails when inserting an array or using a string key. I wrote a function to handle all cases:

function array_insert(&$arr, $index, $val)
{
    if (is_string($index))
        $index = array_search($index, array_keys($arr));
    if (is_array($val))
        array_splice($arr, $index, 0, [$index => $val]);
    else
        array_splice($arr, $index, 0, $val);
}
Dan Bray
  • 5,616
  • 3
  • 43
  • 51
0

You can try it, use this method to make it easy

/**
 * array insert element on position
 * 
 * @link https://vector.cool
 * 
 * @since 1.01.38
 *
 * @param array $original
 * @param mixed $inserted
 * @param int   $position
 * @return array
 */
function array_insert(&$original, $inserted, int $position): array
{
    array_splice($original, $position, 0, array($inserted));
    return $original;
}


$columns = [
    ['name' => '預約項目', 'column' => 'item_name'],
    ['name' => '預約時間', 'column' => 'start_time'],
    ['name' => '預約姓名', 'column' => 'full_name'],
    ['name' => '連絡電話', 'column' => 'phone'],
    ['name' => '建立時間', 'column' => 'create_time']
];
$col = ['name' => '預約帳戶', 'column' => 'user_id'];
$columns = array_insert($columns, $col, 3);
print_r($columns);

Print out:

Array
(
    [0] => Array
        (
            [name] => 預約項目
            [column] => item_name
        )
    [1] => Array
        (
            [name] => 預約時間
            [column] => start_time
        )
    [2] => Array
        (
            [name] => 預約姓名
            [column] => full_name
        )
    [3] => Array
        (
            [name] => 報名人數1
            [column] => num_of_people
        )
    [4] => Array
        (
            [name] => 連絡電話
            [column] => phone
        )
    [5] => Array
        (
            [name] => 預約帳戶
            [column] => user_id
        )
    [6] => Array
        (
            [name] => 建立時間
            [column] => create_time
        )
)
Ann
  • 121
  • 5
0

If you have regular arrays and nothing fancy, this will do. Remember, using array_splice() for inserting elements really means insert before the start index. Be careful when moving elements, because moving up means $targetIndex -1, where as moving down means $targetIndex + 1.

class someArrayClass
{
    private const KEEP_EXISTING_ELEMENTS = 0;

    public function insertAfter(array $array, int $startIndex, $newElements)
    {
        return $this->insertBefore($array, $startIndex + 1, $newElements);
    }

    public function insertBefore(array $array, int $startIndex, $newElements)
    {
        return array_splice($array, $startIndex, self::KEEP_EXISTING_ELEMENTS, $newElements);
    }
}
Anthony Rutledge
  • 4,817
  • 31
  • 40
0
$result_array = array();
$array = array("Tim","John","Mark");
$new_element = "Bill";
$position = 1; 

for ($i=0; $i<count($array); $i++)
    {
      if ($i==$position)
       {
          $result_array[] = $new_element;
       }
       $result_array[] = $array[$i];
    }

print_r($result_array); 

// Result will Array([0] => "Tim",[1] => "Bill", [2] => "John",[1] => "Mark")
  • Welcome to SO! Could you please add some description of what is the advantage of your solution? Thanks. – halanson Mar 04 '21 at 16:40