Insert new item in array on any position in PHP
Asked Answered
A

23

628

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

Aphrodisiac answered 26/9, 2010 at 9:39 Comment(1)
Possible duplicate of How to insert element into arrays at specific position?Antiphony
T
1190

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.

RETURN VALUE: To be noted that the function does not return the desired substitution. The $original is passed by reference and edited in place. See the expression array &$array with & in the parameters list .

Tjader answered 26/9, 2010 at 11:14 Comment(7)
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.Bullis
Just saying that this will not preserve keys in the $inserted array.Stetson
Also in PHP manual, example #1: php.net/manual/en/function.array-splice.phpMavismavra
@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 php.net/manual/en/…Cart
@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.Lashing
@SunilPachlangia For a multidimensional array, this function allowed me to insert an array at a specified position: gist.github.com/wpscholar/0deadce1bbfa4adb4e4c It seems similar to other functions on this page, but I found it easier to understand.Lamarlamarck
It seems that the behaviour of this function changed in PHP 7. Adding an empty array as an array element was possible in PHP 5 but does not seem possible anymore in PHP 7: $x = array('a','b','c','d'); array_splice($x, 2, 0, array());Logorrhea
C
65

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',
  ),
)
Cribb answered 13/9, 2013 at 8:24 Comment(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...Hamal
We can also use $array = array_slice($array, 0, $pos) + $insert + array_slice($array, $pos); instead of array_merge function. The function will return the same output.Yetty
M
44
$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)
Medor answered 26/9, 2010 at 9:46 Comment(4)
Using + instead of array_merge can preserve keysStetson
Now I can add more elements before an INDEXCorettacorette
Array merge only can merge numeric array. So u should use + instead of array_merge.Bounteous
Please ignore all comments that suggest that array_merge() is inappropriate or that the array union operator is appropriate for numeric keys. Watch the union operator fail horribly.Dola
T
12

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);
Tijerina answered 27/4, 2018 at 10:5 Comment(0)
I
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);
}
Illustrate answered 5/10, 2012 at 8:31 Comment(2)
That function does not save the order in array.Trademark
This solution is misleading / poorly implemented. Here is a correction which uses array_splice() prior to merging and properly orders the element assembly. I understand why max()! is used, but it should be explained to researchers in the answer since it is covering a fringe scenario.Dola
A
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 $tmpArray;
}

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;
}
Arelus answered 12/8, 2013 at 12:16 Comment(1)
This works fine. However, in the second example, in your function insertBefore(), you should return $tmpArray instead of $input.Chordate
S
6

This function by Brad Erickson 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.

Sulcus answered 16/8, 2018 at 9:34 Comment(0)
T
6

How to preserve array keys using array_splice()

The answer of @jay.lee is correct, unfortunately it doesn't preserve the keys of an array, as pointed out in the comments:

$original = array( 
    'a' => 'A', 
    'b' => 'B', 
    'c' => 'C', 
    // insert here
    'd' => 'D', 
    'e' => 'E');

$inserted = array( 'x' => 'X' ); 

array_splice( $original, 3, 0, $inserted );
print_r($original);

/* Output
Array
(
    [a] => A
    [b] => B
    [c] => C
    [0] => X  <= the lost key 
    [d] => D
    [e] => E
) */

The simplest way I found to preserve the array keys is to use the array_splice() function and adding the arrays together using + / union operators (also mentioned in the comments of another answer):

$original = array( 
    'a' => 'A', 
    'b' => 'B', 
    'c' => 'C', 
    // insert here
    'd' => 'D', 
    'e' => 'E');

$inserted = array( 'x' => 'X' ); 

// Insert before postion 'd'
$before = array_splice( $original, 0, 3 ); // $original contains the left over

// Merge together
$result = $before + $inserted + $original;
print_r($result);

/* Output
Array
(
    [a] => A
    [b] => B
    [c] => C
    [x] => X
    [d] => D
    [e] => E
) */

Note: using array union operators is only safe when dealing with non-numeric keys


Thanks for the correction @mickmackusa

Tholos answered 8/12, 2022 at 21:53 Comment(1)
@Dola thanks for point that out. I removed that part as it isn't really part of the solution.Tholos
D
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)
    );
} 
Dawn answered 23/10, 2014 at 4:46 Comment(1)
This answer doesn't check if $pos is false.Dola
U
4
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;
}
Ulcer answered 6/3, 2013 at 8:44 Comment(1)
This answer is missing its educational explanation.Dola
S
4

You can use this

foreach ($array as $key => $value) 
{
    if($key==1)
    {
        $new_array[]=$other_array;
    }   
    $new_array[]=$value;    
}
Seafaring answered 25/2, 2017 at 9:24 Comment(1)
This answer is missing its educational explanation.Dola
A
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

Anders answered 9/1, 2014 at 17:25 Comment(1)
This answer is missing its educational explanation.Dola
C
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.

Compony answered 20/10, 2016 at 10:56 Comment(0)
D
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
Divorcement answered 6/3, 2013 at 16:22 Comment(1)
Hint for adding an element at the beginning: array_unshift($a,'i am the new first element');Atencio
J
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;
}
Javierjavler answered 24/3, 2016 at 21:56 Comment(1)
Why try this? This answer is missing its educational explanation.Dola
W
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']);
Wethington answered 13/6, 2019 at 11:23 Comment(1)
This answer is missing its educational explanation.Dola
J
2

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
        )
)
Jinn answered 11/12, 2020 at 13:56 Comment(0)
A
2
$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")
Allegra answered 23/2, 2021 at 21:5 Comment(1)
Welcome to SO! Could you please add some description of what is the advantage of your solution? Thanks.Bair
M
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.

Mitsukomitt answered 25/11, 2012 at 21:18 Comment(0)
H
1

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);
}
Hybris answered 10/11, 2020 at 1:16 Comment(0)
O
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); 
} 
Overdone answered 8/5, 2012 at 16:16 Comment(1)
why not $src = array_merge($array_head, $ins, $array_tail); ?Babble
J
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);
    }
}
Janessajanet answered 14/2, 2021 at 13:39 Comment(0)
S
-3

After working on this for a few days, here was the easiest solution I could find.

$indexnumbertoaddat // this is a variable that points to the index # where you 
want the new array to be inserted

$arrayToAdd = array(array('key' => $value, 'key' => $value)); //this is the new 
 array and it's values that you want to add. //the key here is to write it like 
 array(array('key' =>, since you're adding this array inside another array. This 
 is the point that a lot of answer left out. 

array_splice($originalArray, $indexnumbertoaddatt, 0, $arrayToAdd); //the actual 
splice function. You're doing it to $originalArray, at the index # you define, 
0 means you're just shifting all other index items down 1, and then you add the 
new array. 
Sundried answered 6/10, 2021 at 1:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.