How to insert element into arrays at specific position? - php

Let's imagine that we have two arrays:
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
$array_2 = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3',
);
Now, I'd like to insert array('sample_key' => 'sample_value') after third element of each array. How can I do it?

array_slice() can be used to extract parts of the array, and the union array operator (+) can recombine the parts.
$res = array_slice($array, 0, 3, true) +
array("my_key" => "my_value") +
array_slice($array, 3, count($array)-3, true);
This example:
$array = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3',
);
$res = array_slice($array, 0, 3, true) +
array("my_key" => "my_value") +
array_slice($array, 3, count($array) - 1, true) ;
print_r($res);
gives:
Array
(
[zero] => 0
[one] => 1
[two] => 2
[my_key] => my_value
[three] => 3
)

For your first array, use array_splice():
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
array_splice($array_1, 3, 0, 'more');
print_r($array_1);
output:
Array(
[0] => zero
[1] => one
[2] => two
[3] => more
[4] => three
)
for the second one there is no order so you just have to do :
$array_2['more'] = '2.5';
print_r($array_2);
And sort the keys by whatever you want.

code:
function insertValueAtPosition($arr, $insertedArray, $position) {
$i = 0;
$new_array=[];
foreach ($arr as $key => $value) {
if ($i == $position) {
foreach ($insertedArray as $ikey => $ivalue) {
$new_array[$ikey] = $ivalue;
}
}
$new_array[$key] = $value;
$i++;
}
return $new_array;
}
example:
$array = ["A"=8, "K"=>3];
$insert_array = ["D"= 9];
insertValueAtPosition($array, $insert_array, $position=2);
// result ====> ["A"=>8, "D"=>9, "K"=>3];
May not really look perfect, but it works.

Here's a simple function that you could use. Just plug n play.
This is Insert By Index, Not By Value.
you can choose to pass the array, or use one that you already have declared.
Newer, shorter version:
function insert($array, $index, $val)
{
$size = count($array); //because I am going to use this more than one time
if (!is_int($index) || $index < 0 || $index > $size)
{
return -1;
}
else
{
$temp = array_slice($array, 0, $index);
$temp[] = $val;
return array_merge($temp, array_slice($array, $index, $size));
}
}
Older, longer version:
function insert($array, $index, $val) { //function decleration
$temp = array(); // this temp array will hold the value
$size = count($array); //because I am going to use this more than one time
// Validation -- validate if index value is proper (you can omit this part)
if (!is_int($index) || $index < 0 || $index > $size) {
echo "Error: Wrong index at Insert. Index: " . $index . " Current Size: " . $size;
echo "<br/>";
return false;
}
//here is the actual insertion code
//slice part of the array from 0 to insertion index
$temp = array_slice($array, 0, $index);//e.g index=5, then slice will result elements [0-4]
//add the value at the end of the temp array// at the insertion index e.g 5
array_push($temp, $val);
//reconnect the remaining part of the array to the current temp
$temp = array_merge($temp, array_slice($array, $index, $size));
$array = $temp;//swap// no need for this if you pass the array cuz you can simply return $temp, but, if u r using a class array for example, this is useful.
return $array; // you can return $temp instead if you don't use class array
}
Usage example:
//1
$result = insert(array(1,2,3,4,5),0, 0);
echo "<pre>";
echo "<br/>";
print_r($result);
echo "</pre>";
//2
$result = insert(array(1,2,3,4,5),2, "a");
echo "<pre>";
print_r($result);
echo "</pre>";
//3
$result = insert(array(1,2,3,4,5) ,4, "b");
echo "<pre>";
print_r($result);
echo "</pre>";
//4
$result = insert(array(1,2,3,4,5),5, 6);
echo "<pre>";
echo "<br/>";
print_r($result);
echo "</pre>";
Expected result:
//1
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
)
//2
Array
(
[0] => 1
[1] => 2
[2] => a
[3] => 3
[4] => 4
[5] => 5
)
//3
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => b
[5] => 5
)
//4
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)

$list = array(
'Tunisia' => 'Tunis',
'Germany' => 'Berlin',
'Italy' => 'Rom',
'Egypt' => 'Cairo'
);
$afterIndex = 2;
$newVal= array('Palestine' => 'Jerusalem');
$newList = array_merge(array_slice($list,0,$afterIndex+1), $newVal,array_slice($list,$afterIndex+1));

This function supports:
both numeric and assoc keys
insert before or after the founded key
append to the end of array if key isn't founded
function insert_into_array( $array, $search_key, $insert_key, $insert_value, $insert_after_founded_key = true, $append_if_not_found = false ) {
$new_array = array();
foreach( $array as $key => $value ){
// INSERT BEFORE THE CURRENT KEY?
// ONLY IF CURRENT KEY IS THE KEY WE ARE SEARCHING FOR, AND WE WANT TO INSERT BEFORE THAT FOUNDED KEY
if( $key === $search_key && ! $insert_after_founded_key )
$new_array[ $insert_key ] = $insert_value;
// COPY THE CURRENT KEY/VALUE FROM OLD ARRAY TO A NEW ARRAY
$new_array[ $key ] = $value;
// INSERT AFTER THE CURRENT KEY?
// ONLY IF CURRENT KEY IS THE KEY WE ARE SEARCHING FOR, AND WE WANT TO INSERT AFTER THAT FOUNDED KEY
if( $key === $search_key && $insert_after_founded_key )
$new_array[ $insert_key ] = $insert_value;
}
// APPEND IF KEY ISNT FOUNDED
if( $append_if_not_found && count( $array ) == count( $new_array ) )
$new_array[ $insert_key ] = $insert_value;
return $new_array;
}
USAGE:
$array1 = array(
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four'
);
$array2 = array(
'zero' => '# 0',
'one' => '# 1',
'two' => '# 2',
'three' => '# 3',
'four' => '# 4'
);
$array3 = array(
0 => 'zero',
1 => 'one',
64 => '64',
3 => 'three',
4 => 'four'
);
// INSERT AFTER WITH NUMERIC KEYS
print_r( insert_into_array( $array1, 3, 'three+', 'three+ value') );
// INSERT AFTER WITH ASSOC KEYS
print_r( insert_into_array( $array2, 'three', 'three+', 'three+ value') );
// INSERT BEFORE
print_r( insert_into_array( $array3, 64, 'before-64', 'before-64 value', false) );
// APPEND IF SEARCH KEY ISNT FOUNDED
print_r( insert_into_array( $array3, 'undefined assoc key', 'new key', 'new value', true, true) );
RESULTS:
Array
(
[0] => zero
[1] => one
[2] => two
[3] => three
[three+] => three+ value
[4] => four
)
Array
(
[zero] => # 0
[one] => # 1
[two] => # 2
[three] => # 3
[three+] => three+ value
[four] => # 4
)
Array
(
[0] => zero
[1] => one
[before-64] => before-64 value
[64] => 64
[3] => three
[4] => four
)
Array
(
[0] => zero
[1] => one
[64] => 64
[3] => three
[4] => four
[new key] => new value
)

Simplest solution, if you want to insert (an element or array) after a certain key:
function array_splice_after_key($array, $key, $array_to_insert)
{
$key_pos = array_search($key, array_keys($array));
if($key_pos !== false){
$key_pos++;
$second_array = array_splice($array, $key_pos);
$array = array_merge($array, $array_to_insert, $second_array);
}
return $array;
}
So, if you have:
$array = [
'one' => 1,
'three' => 3
];
$array_to_insert = ['two' => 2];
And execute:
$result_array = array_splice_after_key($array, 'one', $array_to_insert);
You'll have:
Array (
['one'] => 1
['two'] => 2
['three'] => 3
)

I recently wrote a function to do something similar to what it sounds like you're attempting, it's a similar approach to clasvdb's answer.
function magic_insert($index,$value,$input_array ) {
if (isset($input_array[$index])) {
$output_array = array($index=>$value);
foreach($input_array as $k=>$v) {
if ($k<$index) {
$output_array[$k] = $v;
} else {
if (isset($output_array[$k]) ) {
$output_array[$k+1] = $v;
} else {
$output_array[$k] = $v;
}
}
}
} else {
$output_array = $input_array;
$output_array[$index] = $value;
}
ksort($output_array);
return $output_array;
}
Basically it inserts at a specific point, but avoids overwriting by shifting all items down.

Using array_splice instead of array_slice gives one less function call.
$toto = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3'
);
$ret = array_splice($toto, 3 );
$toto = $toto + array("my_key" => "my_value") + $ret;
print_r($toto);

If you don't know that you want to insert it at position #3, but you know the key that you want to insert it after, I cooked up this little function after seeing this question.
/**
* Inserts any number of scalars or arrays at the point
* in the haystack immediately after the search key ($needle) was found,
* or at the end if the needle is not found or not supplied.
* Modifies $haystack in place.
* #param array &$haystack the associative array to search. This will be modified by the function
* #param string $needle the key to search for
* #param mixed $stuff one or more arrays or scalars to be inserted into $haystack
* #return int the index at which $needle was found
*/
function array_insert_after(&$haystack, $needle = '', $stuff){
if (! is_array($haystack) ) return $haystack;
$new_array = array();
for ($i = 2; $i < func_num_args(); ++$i){
$arg = func_get_arg($i);
if (is_array($arg)) $new_array = array_merge($new_array, $arg);
else $new_array[] = $arg;
}
$i = 0;
foreach($haystack as $key => $value){
++$i;
if ($key == $needle) break;
}
$haystack = array_merge(array_slice($haystack, 0, $i, true), $new_array, array_slice($haystack, $i, null, true));
return $i;
}
Here's a codepad fiddle to see it in action: http://codepad.org/5WlKFKfz
Note: array_splice() would have been a lot more efficient than array_merge(array_slice()) but then the keys of your inserted arrays would have been lost. Sigh.

Cleaner approach (based on fluidity of use and less code).
/**
* Insert data at position given the target key.
*
* #param array $array
* #param mixed $target_key
* #param mixed $insert_key
* #param mixed $insert_val
* #param bool $insert_after
* #param bool $append_on_fail
* #param array $out
* #return array
*/
function array_insert(
array $array,
$target_key,
$insert_key,
$insert_val = null,
$insert_after = true,
$append_on_fail = false,
$out = [])
{
foreach ($array as $key => $value) {
if ($insert_after) $out[$key] = $value;
if ($key == $target_key) $out[$insert_key] = $insert_val;
if (!$insert_after) $out[$key] = $value;
}
if (!isset($array[$target_key]) && $append_on_fail) {
$out[$insert_key] = $insert_val;
}
return $out;
}
Usage:
$colors = [
'blue' => 'Blue',
'green' => 'Green',
'orange' => 'Orange',
];
$colors = array_insert($colors, 'blue', 'pink', 'Pink');
die(var_dump($colors));

This is an old question, but I posted a comment in 2014 and frequently come back to this. I thought I would leave a full answer. This isn't the shortest solution but it is quite easy to understand.
Insert a new value into an associative array, at a numbered position, preserving keys, and preserving order.
$columns = array(
'id' => 'ID',
'name' => 'Name',
'email' => 'Email',
'count' => 'Number of posts'
);
$columns = array_merge(
array_slice( $columns, 0, 3, true ), // The first 3 items from the old array
array( 'subscribed' => 'Subscribed' ), // New value to add after the 3rd item
array_slice( $columns, 3, null, true ) // Other items after the 3rd
);
print_r( $columns );
/*
Array (
[id] => ID
[name] => Name
[email] => Email
[subscribed] => Subscribed
[count] => Number of posts
)
*/

I do that as
$slightly_damaged = array_merge(
array_slice($slightly_damaged, 0, 4, true) + ["4" => "0.0"],
array_slice($slightly_damaged, 4, count($slightly_damaged) - 4, true)
);

This is another solution in PHP 7.1
/**
* #param array $input Input array to add items to
* #param array $items Items to insert (as an array)
* #param int $position Position to inject items from (starts from 0)
*
* #return array
*/
function arrayInject( array $input, array $items, int $position ): array
{
if (0 >= $position) {
return array_merge($items, $input);
}
if ($position >= count($input)) {
return array_merge($input, $items);
}
return array_merge(
array_slice($input, 0, $position, true),
$items,
array_slice($input, $position, null, true)
);
}

I just created an ArrayHelper class that would make this very easy for numeric indexes.
class ArrayHelper
{
/*
Inserts a value at the given position or throws an exception if
the position is out of range.
This function will push the current values up in index. ex. if
you insert at index 1 then the previous value at index 1 will
be pushed to index 2 and so on.
$pos: The position where the inserted value should be placed.
Starts at 0.
*/
public static function insertValueAtPos(array &$array, $pos, $value) {
$maxIndex = count($array)-1;
if ($pos === 0) {
array_unshift($array, $value);
} elseif (($pos > 0) && ($pos <= $maxIndex)) {
$firstHalf = array_slice($array, 0, $pos);
$secondHalf = array_slice($array, $pos);
$array = array_merge($firstHalf, array($value), $secondHalf);
} else {
throw new IndexOutOfBoundsException();
}
}
}
Example:
$array = array('a', 'b', 'c', 'd', 'e');
$insertValue = 'insert';
\ArrayHelper::insertValueAtPos($array, 3, $insertValue);
Beginning $array:
Array (
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
)
Result:
Array (
[0] => a
[1] => b
[2] => c
[3] => insert
[4] => d
[5] => e
)

This is better method how insert item to array on some position.
function arrayInsert($array, $item, $position)
{
$begin = array_slice($array, 0, $position);
array_push($begin, $item);
$end = array_slice($array, $position);
$resultArray = array_merge($begin, $end);
return $resultArray;
}

I needed something that could do an insert before, replace, after the key; and add at the start or end of the array if target key is not found. Default is to insert after the key.
New Function
/**
* Insert element into an array at a specific key.
*
* #param array $input_array
* The original array.
* #param array $insert
* The element that is getting inserted; array(key => value).
* #param string $target_key
* The key name.
* #param int $location
* 1 is after, 0 is replace, -1 is before.
*
* #return array
* The new array with the element merged in.
*/
function insert_into_array_at_key(array $input_array, array $insert, $target_key, $location = 1) {
$output = array();
$new_value = reset($insert);
$new_key = key($insert);
foreach ($input_array as $key => $value) {
if ($key === $target_key) {
// Insert before.
if ($location == -1) {
$output[$new_key] = $new_value;
$output[$key] = $value;
}
// Replace.
if ($location == 0) {
$output[$new_key] = $new_value;
}
// After.
if ($location == 1) {
$output[$key] = $value;
$output[$new_key] = $new_value;
}
}
else {
// Pick next key if there is an number collision.
if (is_numeric($key)) {
while (isset($output[$key])) {
$key++;
}
}
$output[$key] = $value;
}
}
// Add to array if not found.
if (!isset($output[$new_key])) {
// Before everything.
if ($location == -1) {
$output = $insert + $output;
}
// After everything.
if ($location == 1) {
$output[$new_key] = $new_value;
}
}
return $output;
}
Input code
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
$array_2 = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3',
);
$array_1 = insert_into_array_at_key($array_1, array('sample_key' => 'sample_value'), 2, 1);
print_r($array_1);
$array_2 = insert_into_array_at_key($array_2, array('sample_key' => 'sample_value'), 'two', 1);
print_r($array_2);
Output
Array
(
[0] => zero
[1] => one
[2] => two
[sample_key] => sample_value
[3] => three
)
Array
(
[zero] => 0
[one] => 1
[two] => 2
[sample_key] => sample_value
[three] => 3
)

Very simple 2 string answer to your question:
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
At first you insert anything to your third element with array_splice and then assign a value to this element:
array_splice($array_1, 3, 0 , true);
$array_1[3] = array('sample_key' => 'sample_value');

Not as concrete as the answer of Artefacto, but based in his suggestion of using array_slice(), I wrote the next function:
function arrayInsert($target, $byKey, $byOffset, $valuesToInsert, $afterKey) {
if (isset($byKey)) {
if (is_numeric($byKey)) $byKey = (int)floor($byKey);
$offset = 0;
foreach ($target as $key => $value) {
if ($key === $byKey) break;
$offset++;
}
if ($afterKey) $offset++;
} else {
$offset = $byOffset;
}
$targetLength = count($target);
$targetA = array_slice($target, 0, $offset, true);
$targetB = array_slice($target, $offset, $targetLength, true);
return array_merge($targetA, $valuesToInsert, $targetB);
}
Features:
Inserting one or múltiple values
Inserting key value pair(s)
Inserting before/after the key, or by offset
Usage examples:
$target = [
'banana' => 12,
'potatoe' => 6,
'watermelon' => 8,
'apple' => 7,
2 => 21,
'pear' => 6
];
// Values must be nested in an array
$insertValues = [
'orange' => 0,
'lemon' => 3,
3
];
// By key
// Third parameter is not applicable
// Insert after 2 (before 'pear')
var_dump(arrayInsert($target, 2, null, $valuesToInsert, true));
// Insert before 'watermelon'
var_dump(arrayInsert($target, 'watermelon', null, $valuesToInsert, false));
// By offset
// Second and last parameter are not applicable
// Insert in position 2 (zero based i.e. before 'watermelon')
var_dump(arrayInsert($target, null, 2, $valuesToInsert, null));

In case you are just looking to insert an item into an array at a certain position (based on #clausvdb answer):
function array_insert($arr, $insert, $position) {
$i = 0;
$ret = array();
foreach ($arr as $key => $value) {
if ($i == $position) {
$ret[] = $insert;
}
$ret[] = $value;
$i++;
}
return $ret;
}

Here is my version:
/**
*
* Insert an element after an index in an array
* #param array $array
* #param string|int $key
* #param mixed $value
* #param string|int $offset
* #return mixed
*/
function array_splice_associative($array, $key, $value, $offset) {
if (!is_array($array)) {
return $array;
}
if (array_key_exists($key, $array)) {
unset($array[$key]);
}
$return = array();
$inserted = false;
foreach ($array as $k => $v) {
$return[$k] = $v;
if ($k == $offset && !$inserted) {
$return[$key] = $value;
$inserted = true;
}
}
if (!$inserted) {
$return[$key] = $value;
}
return $return;
}

try this one ===
$key_pos=0;
$a1=array("a"=>"red", "b"=>"green", "c"=>"blue", "d"=>"yellow");
$arrkey=array_keys($a1);
array_walk($arrkey,function($val,$key) use(&$key_pos) {
if($val=='b')
{
$key_pos=$key;
}
});
$a2=array("e"=>"purple");
$newArray = array_slice($a1, 0, $key_pos, true) + $a2 +
array_slice($a1, $key_pos, NULL, true);
print_r($newArray);
Output
Array (
[a] => red
[e] => purple
[b] => green
[c] => blue
[d] => yellow )

This can be done by array.splice(). Please note array_splice or array_merge doesn't preserve keys for associative arrays. So array_slice is used and '+' operator is used for concatenating the two arrays.
More details here
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
$array_2 = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3',
);
$index = 2;
$finalArray = array_slice($array_1, 0, $index, true) +
$array2 +
array_slice($array_2, $index, NULL, true);
print_r($finalArray);
/*
Array
(
[0] => zero
[1] => one
[10] => grapes
[z] => mangoes
[two] => 2
[three] => 3
)
*/

I've created a function (PHP 8.1), which allows you to insert items to associative or numeric arrays:
function insertItemsToPosition(array $array, string|int $insertAfterPosition, array $itemsToAdd): array
{
$insertAfterIndex = array_search($insertAfterPosition, array_keys($array), true);
if ($insertAfterIndex === false) {
throw new \UnexpectedValueException(sprintf('You try to insert items to an array after the key "%s", but this key is not existing in given array. Available keys are: %s', $insertAfterPosition, implode(', ', array_keys($array))));
}
$itemsBefore = array_slice($array, 0, $insertAfterIndex + 1);
$itemsAfter = array_slice($array, $insertAfterIndex + 1);
return $itemsBefore + $itemsToAdd + $itemsAfter;
}

You can insert elements during a foreach loop, since this loop works on a copy of the original array, but you have to keep track of the number of inserted lines (I call this "bloat" in this code):
$bloat=0;
foreach ($Lines as $n=>$Line)
{
if (MustInsertLineHere($Line))
{
array_splice($Lines,$n+$bloat,0,"string to insert");
++$bloat;
}
}
Obviously, you can generalize this "bloat" idea to handle arbitrary insertions and deletions during the foreach loop.

Related

How to sum Array values in php? [duplicate]

How can I add all the columnar values by associative key? Note that key sets are dynamic.
Input array:
Array
(
[0] => Array
(
[gozhi] => 2
[uzorong] => 1
[ngangla] => 4
[langthel] => 5
)
[1] => Array
(
[gozhi] => 5
[uzorong] => 0
[ngangla] => 3
[langthel] => 2
)
[2] => Array
(
[gozhi] => 3
[uzorong] => 0
[ngangla] => 1
[langthel] => 3
)
)
Desired result:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
You can use array_walk_recursive() to get a general-case solution for your problem (the one when each inner array can possibly have unique keys).
$final = array();
array_walk_recursive($input, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
Example with array_walk_recursive() for the general case
Also, since PHP 5.5 you can use the array_column() function to achieve the result you want for the exact key, [gozhi], for example :
array_sum(array_column($input, 'gozhi'));
Example with array_column() for the specified key
If you want to get the total sum of all inner arrays with the same keys (the desired result that you've posted), you can do something like this (bearing in mind that the first inner array must have the same structure as the others) :
$final = array_shift($input);
foreach ($final as $key => &$value){
$value += array_sum(array_column($input, $key));
}
unset($value);
Example with array_column() in case all inner arrays have the same keys
If you want a general-case solution using array_column() then at first you may consider to get all unique keys , and then get the sum for each key :
$final = array();
foreach($input as $value)
$final = array_merge($final, $value);
foreach($final as $key => &$value)
$value = array_sum(array_column($input, $key));
unset($value);
Example with array_column() for the general case
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
isset($sumArray[$id]) || $sumArray[$id] = 0;
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
Use this snippet:
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Here is a solution similar to the two others:
$acc = array_shift($arr);
foreach ($arr as $val) {
foreach ($val as $key => $val) {
$acc[$key] += $val;
}
}
But this doesn’t need to check if the array keys already exist and doesn’t throw notices neither.
It can also be done using array_map :
$rArray = array(
0 => array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
),
1 => array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
),
2 => array(
'gozhi' => 3,
'uzorong' => 0,
'ngangla' => 1,
'langthel' => 3
),
);
$sumResult = call_user_func_array('array_map', array_merge(['sum'], $rArray));
function sum()
{
return array_sum(func_get_args());
}
$newarr=array();
foreach($arrs as $value)
{
foreach($value as $key=>$secondValue)
{
if(!isset($newarr[$key]))
{
$newarr[$key]=0;
}
$newarr[$key]+=$secondValue;
}
}
Another version, with some benefits below.
$sum = ArrayHelper::copyKeys($arr[0]);
foreach ($arr as $item) {
ArrayHelper::addArrays($sum, $item);
}
class ArrayHelper {
public function addArrays(Array &$to, Array $from) {
foreach ($from as $key=>$value) {
$to[$key] += $value;
}
}
public function copyKeys(Array $from, $init=0) {
return array_fill_keys(array_keys($from), $init);
}
}
I wanted to combine the best of Gumbo's, Graviton's, and Chris J's answer with the following goals so I could use this in my app:
a) Initialize the 'sum' array keys outside of the loop (Gumbo). Should help with performance on very large arrays (not tested yet!). Eliminates notices.
b) Main logic is easy to understand without hitting the manuals. (Graviton, Chris J).
c) Solve the more general problem of adding the values of any two arrays with the same keys and make it less dependent on the sub-array structure.
Unlike Gumbo's solution, you could reuse this in cases where the values are not in sub arrays. Imagine in the example below that $arr1 and $arr2 are not hard-coded, but are being returned as the result of calling a function inside a loop.
$arr1 = array(
'gozhi' => 2,
'uzorong' => 1,
'ngangla' => 4,
'langthel' => 5
);
$arr2 = array(
'gozhi' => 5,
'uzorong' => 0,
'ngangla' => 3,
'langthel' => 2
);
$sum = ArrayHelper::copyKeys($arr1);
ArrayHelper::addArrays($sum, $arr1);
ArrayHelper::addArrays($sum, $arr2);
It can also be done using array_walk:
function array_sum_values(array $input, $key) {
$sum = 0;
array_walk($input, function($item, $index, $params) {
if (!empty($item[$params[1]]))
$params[0] += $item[$params[1]];
}, array(&$sum, $key)
);
return $sum;
}
var_dump(array_sum_values($arr, 'gozhi'));
Not so readable like previous solutions but it works :)
Go through each item of the array and sum values to previous values if they exist, if not just assign the value.
<?php
$array =
[
[
'a'=>1,
'b'=>1,
'c'=>1,
],
[
'a'=>2,
'b'=>2,
],
[
'a'=>3,
'd'=>3,
]
];
$result = array_reduce($array, function($carry, $item) {
foreach($item as $k => $v)
$carry[$k] = $v + ($carry[$k] ?? 0);
return $carry;
}, []);
print_r($result);
Output:
Array
(
[a] => 6
[b] => 3
[c] => 1
[d] => 3
)
Or just loop through each sub array, and group the values for each column. Eventually summing them:
foreach($array as $subarray)
foreach($subarray as $key => $value)
$grouped[$key][] = $value;
$sums = array_map('array_sum', $grouped);
Here's a version where the array keys may not be the same for both arrays, but you want them all to be there in the final array.
function array_add_by_key( $array1, $array2 ) {
foreach ( $array2 as $k => $a ) {
if ( array_key_exists( $k, $array1 ) ) {
$array1[$k] += $a;
} else {
$array1[$k] = $a;
}
}
return $array1;
}
We need to check first if array key does exist.
CODE:
$sum = array();
foreach ($array as $key => $sub_array) {
foreach ($sub_array as $sub_key => $value) {
//If array key doesn't exists then create and initize first before we add a value.
//Without this we will have an Undefined index error.
if( ! array_key_exists($sub_key, $sum)) $sum[$sub_key] = 0;
//Add Value
$sum[$sub_key]+=$value;
}
}
print_r($sum);
OUTPUT With Array Key Validation:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
OUTPUT Without Array Key Validation:
Notice: Undefined index: gozhi in F:\web\index.php on line 37
Notice: Undefined index: uzorong in F:\web\index.php on line 37
Notice: Undefined index: ngangla in F:\web\index.php on line 37
Notice: Undefined index: langthel in F:\web\index.php on line 37
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
This is a bad practice although it prints the output. Always check first if key does exist.
Simple example with array_reduce()
$numbers = [10,20,30];
$total = 0;
foreach ($numbers as $number) {
$total += $number;
}
echo $total; // 60
=>
$numbers = [10,20,30];
$total = array_reduce($numbers, function ($previous, $current) {
return $previous + $current;
});
echo $total; // 60
With assoc array:
$carts = [
['item' => 'A', 'qty' => 2, 'price' => 10],
['item' => 'B', 'qty' => 3, 'price' => 20],
['item' => 'C', 'qty' => 5, 'price' => 30]
];
$total = array_reduce(
$carts,
function ($prev, $item) {
return $prev + $item['qty'] * $item['price'];
}
);
echo $total; // 155
More info => https://www.phptutorial.net/php-tutorial/php-array_reduce/
For those who landed here and are searching for a solution that merges N arrays AND also sums the values of identical keys found in the N arrays, I've written this function that works recursively as well. (See: https://gist.github.com/Nickology/f700e319cbafab5eaedc)
Example:
$a = array( "A" => "bob", "sum" => 10, "C" => array("x","y","z" => 50) );
$b = array( "A" => "max", "sum" => 12, "C" => array("x","y","z" => 45) );
$c = array( "A" => "tom", "sum" => 8, "C" => array("x","y","z" => 50, "w" => 1) );
print_r(array_merge_recursive_numeric($a,$b,$c));
Will result in:
Array
(
[A] => tom
[sum] => 30
[C] => Array
(
[0] => x
[1] => y
[z] => 145
[w] => 1
)
)
Here's the code:
<?php
/**
* array_merge_recursive_numeric function. Merges N arrays into one array AND sums the values of identical keys.
* WARNING: If keys have values of different types, the latter values replace the previous ones.
*
* Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc
* #params N arrays (all parameters must be arrays)
* #author Nick Jouannem <nick#nickology.com>
* #access public
* #return void
*/
function array_merge_recursive_numeric() {
// Gather all arrays
$arrays = func_get_args();
// If there's only one array, it's already merged
if (count($arrays)==1) {
return $arrays[0];
}
// Remove any items in $arrays that are NOT arrays
foreach($arrays as $key => $array) {
if (!is_array($array)) {
unset($arrays[$key]);
}
}
// We start by setting the first array as our final array.
// We will merge all other arrays with this one.
$final = array_shift($arrays);
foreach($arrays as $b) {
foreach($final as $key => $value) {
// If $key does not exist in $b, then it is unique and can be safely merged
if (!isset($b[$key])) {
$final[$key] = $value;
} else {
// If $key is present in $b, then we need to merge and sum numeric values in both
if ( is_numeric($value) && is_numeric($b[$key]) ) {
// If both values for these keys are numeric, we sum them
$final[$key] = $value + $b[$key];
} else if (is_array($value) && is_array($b[$key])) {
// If both values are arrays, we recursively call ourself
$final[$key] = array_merge_recursive_numeric($value, $b[$key]);
} else {
// If both keys exist but differ in type, then we cannot merge them.
// In this scenario, we will $b's value for $key is used
$final[$key] = $b[$key];
}
}
}
// Finally, we need to merge any keys that exist only in $b
foreach($b as $key => $value) {
if (!isset($final[$key])) {
$final[$key] = $value;
}
}
}
return $final;
}
?>
Here you have how I usually do this kind of operations.
// We declare an empty array in wich we will store the results
$sumArray = array();
// We loop through all the key-value pairs in $myArray
foreach ($myArray as $k=>$subArray) {
// Each value is an array, we loop through it
foreach ($subArray as $id=>$value) {
// If $sumArray has not $id as key we initialize it to zero
if(!isset($sumArray[$id])){
$sumArray[$id] = 0;
}
// If the array already has a key named $id, we increment its value
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
You can try this:
$c = array_map(function () {
return array_sum(func_get_args());
},$a, $b);
and finally:
print_r($c);
this works great on my laravel project
print_r($Array); // your original array
$_SUM = [];
// count($Array[0]) => if the number of keys are equall in all arrays then do a count of index 0 etc.
for ($i=0; $i < count($Array[0]); $i++) {
$_SUM[] = $Array[0][$i] + $Array[1][$i]; // do a for loop on the count
}
print_r($_SUM); // get a sumed up array
$sumArray = array();
foreach ($myArray as $k => $subArray) {
foreach ($subArray as $id => $value) {
if (!isset($sumArray[$id])) {
$sumArray[$id] = 0;
}
$sumArray[$id]+=$value;
}
}
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
if(!isset($sumArray[$id])){
$sumArray[$id] =$value;
}else {
$sumArray[$id]+=$value;
}
}
}
print_r($sumArray);
`
For example, you can pluck all fields from a result like this below.
I am picking out the 'balance' from an array and save to a variable
$kii = $user->pluck('balance');
then on the next line u can sum like this:
$sum = $kii->sum();
Hope it helps.
Code here:
$temp_arr = [];
foreach ($a as $k => $v) {
if(!is_null($v)) {
$sum = isset($temp_arr[$v[0]]) ? ((int)$v[5] + $sum) : (int)$v[5];
$temp_arr[$v[0]] = $sum;
}
}
return $temp_arr;
Result:
{SEQ_OK: 1328,SEQ_ERROR: 561}

PHP: Get the keys with the longest string in an associative array

I want to first get the keys with the same values and then keep the keys with the longest string. Here is the code compiled so far:
<?php
$data = array('Anna' => 1, 'Ann' => 1, 'Tommy' => 100, 'Tom' => 100);
$total = array_count_values($data);
$filtered = array_filter($data, function ($value) use ($total) {
return $total[$value] > 1;
});
print_r($filtered);
?>
The current output:
Array ( [Anna] => 1 [Ann] => 1 [Tommy] => 100 [Tom] => 100 )
My expected output:
Array ( [Anna] => 1 [Tommy] => 100)
Many thanks for help.
Not necessarily the most optimized solution, but you could write it up using simple check:
$data = array('Anna' => 1, 'Ann' => 1, 'Tommy' => 100, 'Tom' => 100, 'Dan' => 200, 'Danny' => 200);
$total = array_count_values($data);
$filtered = array_filter($data, function ($value) use ($total) {
return $total[$value] > 1;
});
foreach($data as $key => $value) {
$foundKey = array_search($value,$filtered);
if($foundKey){
if(strlen($foundKey) < strlen($key)){
unset($filtered[$foundKey]);
} elseif(strlen($foundKey) > strlen($key)) {
unset($filtered[$key]);
}
}
}
print_r($filtered);
Not sure to post it after even answer is accepted but I have simple hack for this using ksort() and array_flip():
$data = array('Anna' => 1, 'Ann' => 1, 'Tommy' => 100, 'Tom' => 100, 'Dan' => 200, 'Danny' => 200);
ksort($data);
$result=array_flip(array_flip($data));
print_r($result);
ksort(): Sort an array by key
array_flip(): Flip all keys with their associated values in an array
Demo

How to get unique array whose near values

I have an array.
$a = array(
0 => 1,
1 => 1,
2 => 2,
3 => 3,
4 => 1
);
How to get unique array like this?
$result = array_My_unique($a);
print_r($result);
Output:
$a = array(
0 => 1,
1 => 2,
2 => 3,
3 => 1
);
Thank!
Assuming you are trying to avoid duplicates that are immediately next to each other:
function array_my_unique($a = array()) {
$out = array();
$curr = false;
foreach ($a as $v) {
if ($curr !== $v) {
$out[] = $v;
}
$curr = $v;
}
return $out;
}
This satisfies the assertion between input/output that you described in the question.

replace array keys with given respective keys

I have an array like below
$old = array(
'a' => 'blah',
'b' => 'key',
'c' => 'amazing',
'd' => array(
0 => 'want to replace',
1 => 'yes I want to'
)
);
I have another array having keys to replace with key information.
$keyReplaceInfoz = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD');
I need to replace all keys of array $old with respective values in array $keyReplaceInfo.
Output should be like this
$old = array(
'newA' => 'blah',
'newB' => 'key',
'newC' => 'amazing',
'newD' => array(
0 => 'want to replace',
1 => 'yes I want to'
)
);
I had to do it manually as below. I am expecting better option. can anyone suggest better way to accomplish this?
$new = array();
foreach ($old as $key => $value)
{
$new[$keyReplaceInfoz[$key]] = $value;
}
I know this can be more simpler.
array_combine(array_merge($old, $keyReplaceInfoz), $old)
I think this looks easier than what you posed.
array_combine(
['newKey1', 'newKey2', 'newKey3'],
array_values(['oldKey1' => 1, 'oldKey2' => 2, 'oldKey3' => 3])
);
This should do the trick as long as you have the same number of values and the same order.
IMO using array_combine, array_merge, even array_intersect_key is overkill.
The original code is good enough, and very fast.
Adapting #shawn-k solution, here is more cleaner code using array_walk, it will only replace desired keys, of course you can modify as per your convenience
array_walk($old, function($value,$key)use ($keyReplaceInfoz,&$old){
$newkey = array_key_exists($key,$keyReplaceInfoz)?$keyReplaceInfoz[$key]:false;
if($newkey!==false){$old[$newkey] = $value;unset($old[$key]);
}
});
print_r($old);
I just solved this same problem in my own application, but for my application $keyReplaceInfoz acts like the whitelist- if a key is not found, that whole element is removed from the resulting array, while the matching whitelisted keys get translated to the new values.
I suppose you could apply this same algorithm maybe with less total code by clever usage of array_map (http://php.net/manual/en/function.array-map.php), which perhaps another generous reader will do.
function filterOldToAllowedNew($key_to_test){
return isset($keyReplaceInfoz[$key_to_test])?$keyReplaceInfoz[$key_to_test]:false;
}
$newArray = array();
foreach($old as $key => $value){
$newkey = filterOldToAllowedNew($key);
if($newkey){
$newArray[$newkey] = $value;
}
}
print_r($newArray);
This question is old but since it comes up first on Google I thought I'd add solution.
// Subject
$old = array('foo' => 1, 'baz' => 2, 'bar' => 3));
// Translations
$tr = array('foo'=>'FOO', 'bar'=>'BAR');
// Get result
$new = array_combine(preg_replace(array_map(function($s){return "/^$s$/";},
array_keys($tr)),$tr, array_keys($old)), $old);
// Output
print_r($new);
Result:
Array
(
[FOO] => 1
[baz] => 2
[BAR] => 3
)
This the solution i have implemented for the same subject:
/**
* Replace keys of given array by values of $keys
* $keys format is [$oldKey=>$newKey]
*
* With $filter==true, will remove elements with key not in $keys
*
* #param array $array
* #param array $keys
* #param boolean $filter
*
* #return $array
*/
function array_replace_keys(array $array,array $keys,$filter=false)
{
$newArray=[];
foreach($array as $key=>$value)
{
if(isset($keys[$key]))
{
$newArray[$keys[$key]]=$value;
}
elseif(!$filter)
{
$newArray[$key]=$value;
}
}
return $newArray;
}
This works irrespective of array order & array count. Output order & value will be based on replaceKey.
$replaceKey = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD', 'e' => 'newE','f'=>'newF');
$array = array(
'a' => 'blah',
'd' => array(
0 => 'want to replace',
1 => 'yes I want to'
),
'noKey'=>'RESIDUAL',
'c' => 'amazing',
'b' => 'key',
);
$filterKey = array_intersect_key($replaceKey,$array);
$filterarray = array_intersect_key(array_merge($filterKey,$array),$filterKey);
$replaced = array_combine($filterKey,$filterarray);
//output
var_export($replaced);
//array ( 'newA' => 'blah', 'newB' => 'key', 'newC' => 'amazing', 'newD' => array ( 0 => 'want to replace', 1 => 'yes I want to' ) )
If you're looking for a recursive solution to use on a multidimensional array, have a look at the below method. It will replace all keys requested, and leave all other keys alone.
/**
* Given an array and a set of `old => new` keys,
* will recursively replace all array keys that
* are old with their corresponding new value.
*
* #param mixed $array
* #param array $old_to_new_keys
*
* #return array
*/
function array_replace_keys($array, array $old_to_new_keys)
{
if(!is_array($array)){
return $array;
}
$temp_array = [];
$ak = array_keys($old_to_new_keys);
$av = array_values($old_to_new_keys);
foreach($array as $key => $value){
if(array_search($key, $ak, true) !== false){
$key = $av[array_search($key, $ak)];
}
if(is_array($value)){
$value = array_replace_keys($value, $old_to_new_keys);
}
$temp_array[$key] = $value;
}
return $temp_array;
}
Using OP's example array:
$old = array(
'a' => 'blah',
'b' => 'key',
'c' => 'amazing',
'd' => array(
0 => 'want to replace',
1 => 'yes I want to'
)
);
$replace = ["a" => "AA", 1 => 11];
var_export(array_replace_keys($old, $replace));
Gives the following output:
array (
'AA' => 'blah',
'b' => 'key',
'c' => 'amazing',
'd' =>
array (
0 => 'want to replace',
11 => 'yes I want to',
),
)
DEMO
Inspired by the following snippet.
This uses #Summoner's example but keeps #Leigh's hint in mind:
$start = microtime();
$array = [ "a" => 1, "b" => 2, "c" => 3 ];
function array_replace_key($array, $oldKey, $newKey) {
$keys = array_keys($array);
$idx = array_search($oldKey, $keys);
array_splice($keys, $idx, 1, $newKey);
return array_combine($keys, array_values($array));
}
print_r(array_replace_key($array, "b", "z"));
<?php
$new = array();
foreach ($old as $key => $value)
{
$new[$keyReplaceInfoz][$key] = $value;
}
?>

Insert new item in array on any position in PHP

How can I insert a new item into an array on any position, for example in the middle of array?
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 .
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',
),
)
$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)
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);
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);
}
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;
}
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.
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)
);
}
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;
}
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
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.
You can use this
foreach ($array as $key => $value)
{
if($key==1)
{
$new_array[]=$other_array;
}
$new_array[]=$value;
}
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
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;
}
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']);
$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")
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
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.
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
)
)
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);
}
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);
}
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);
}
}
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.

Categories