Skip to content

Instantly share code, notes, and snippets.

@IAmAdamTaylor
Last active April 17, 2024 10:07
Show Gist options
  • Save IAmAdamTaylor/39f505365097e5852127c08a4732f43d to your computer and use it in GitHub Desktop.
Save IAmAdamTaylor/39f505365097e5852127c08a4732f43d to your computer and use it in GitHub Desktop.
PHP — Insert an associative array into another associative array, before or after, a specific key in the original array
<?php
/**
* Inserts an associative array (keys & values) into another
* associative array, with the inserted array being placed
* before or after a specific key in the original array.
*
* If any keys in $insert exist in the original $array, their values
* will be overwritten with the values from $insert.
* Those keys will also be moved to the place they are being inserted.
* @see tests/examples for more details.
*
* A new merged array is returned. Original variables are not mutated.
*
* @param array $array The original associative array.
* @param array $insert An associative array of elements to insert.
* @param string $key The key which $insert should be added before or after.
* @param integer $relative Where to insert the new elements.
* >= 0 == after the key specified.
* < 0 == before the key specified.
* Defaults to after (1)
* @return array A new array with all elements from $array and $insert.
*/
function array_insert_assoc_at_key( $array, $insert, $key, $relative = 1 ) {
// find position of $key
$keys = array_keys( $array );
$index = array_search($key, $keys);
// by default slicing on this $index will result in $key being
// included in the *after* slice
//
// if we want it to be included in the before slice, and therefore
// $insert to be added after it, we need to increase the index by 1
if ( $relative >= 0 ) {
$index++;
}
// handle duplicate keys
// unset existing so they are overwritten by newly inserted ones
foreach ($insert as $_key => $_value) {
if ( isset($array[$_key]) ) {
unset($array[$_key]);
}
}
$slice_before = array_slice($array, 0, $index, true);
$slice_after = array_slice($array, $index, null, true);
return array_merge( $slice_before, $insert, $slice_after );
}
<?php
$array = [
'one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
];
// insert fractional values for two after $key == 'two'
$insert_two_fractions = [
'two-quarter' => 2.25,
'two-half' => 2.5,
'two-threequarter' => 2.75,
];
$merged_two_fractions = array_insert_assoc_at_key( $array, $insert_two_fractions, 'two' );
print_r($merged_two_fractions);
/**
* prints:
* Array
(
[one] => 1
[two] => 2
[two-quarter] => 2.25
[two-half] => 2.5
[two-threequarter] => 2.75
[three] => 3
[four] => 4
[five] => 5
)
*/
// insert fractional values for one before $key == 'two'
$insert_before_two = [
'one-99' => 1.99,
];
$merged_before_two = array_insert_assoc_at_key( $array, $insert_before_two, 'two', -1 );
print_r($merged_before_two);
/**
* prints:
* Array
(
[one] => 1
[one-99] => 1.99
[two] => 2
[three] => 3
[four] => 4
[five] => 5
)
*/
// insert keys which already exist within $array
// NOTE: these keys will all be moved to after $key == 'five',
// regardless of their original position within the $array
$insert_duplicate_keys = [
'one' => 'une',
'three' => 'trois',
'five' => 'cinq',
];
$merged_duplicate_keys = array_insert_assoc_at_key( $array, $insert_duplicate_keys, 'five', 1 );
print_r($merged_duplicate_keys);
/**
* prints:
* Array
(
[two] => 2
[four] => 4
[one] => une
[three] => trois
[five] => cinq
)
*/
// if we instead insert them before $key == 'four', then they will be placed at that point
$merged_duplicate_keys_2 = array_insert_assoc_at_key( $array, $insert_duplicate_keys, 'four', -1 );
print_r($merged_duplicate_keys_2);
/**
* prints:
* Array
(
[two] => 2
[one] => une
[three] => trois
[five] => cinq
[four] => 4
)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment