Как эффективно вставлять элементы после другого известного (по ключу или указателю) элемента в массиве PHP?
Учитывая массив:
$a = array(
'abc',
123,
'k1'=>'v1',
'k2'=>'v2',
78,
'tt',
'k3'=>'v3'
);
С его внутренним указателем на один из его элементов, как я могу вставить элемент после текущего элемента?
И как мне вставить элемент после ключевого элемента, например 'k1'?
Усиление производительности ~
Ответы
Ответ 1
Вы можете сделать это, разбив массив с помощью array_keys
и array_values
, затем соедините их оба, затем снова объедините их.
$insertKey = 'k1';
$keys = array_keys($arr);
$vals = array_values($arr);
$insertAfter = array_search($insertKey, $keys) + 1;
$keys2 = array_splice($keys, $insertAfter);
$vals2 = array_splice($vals, $insertAfter);
$keys[] = "myNewKey";
$vals[] = "myNewValue";
$newArray = array_merge(array_combine($keys, $vals), array_combine($keys2, $vals2));
Ответ 2
Я нашел отличный ответ здесь, который работает очень хорошо. Я хочу документировать его, поэтому другие на SO могут легко найти:
/*
* Inserts a new key/value before the key in the array.
*
* @param $key
* The key to insert before.
* @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_after()
*/
function array_insert_before($key, array &$array, $new_key, $new_value) {
if (array_key_exists($key, $array)) {
$new = array();
foreach ($array as $k => $value) {
if ($k === $key) {
$new[$new_key] = $new_value;
}
$new[$k] = $value;
}
return $new;
}
return FALSE;
}
/*
* 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;
}
Ответ 3
Вы не можете использовать внутренний указатель массива для вставки элементов.
Здесь array_splice
, который может вставлять/удалять/заменять элементы и подмассивы, но он предназначен для массивов с индексом с целыми числами.
Я боюсь, вам придется перестроить массив для вставки элемента (за исключением случаев, когда вы хотите вставить первый/последний элемент) или использовать отдельный массив с индексом целых чисел для хранения ключей в том порядке, в котором вы хотите.
Ответ 4
В общем случае двусвязный список идеально подходит для этой задачи.
Существует встроенная реализация этого с PHP 5.3, называемая SplDoublyLinkedList, а так как PHP 5.5 также имеет добавить метод, который позволяет добавлять/вставлять значения в середине.
Ответ 5
Этот способ отлично подходит для новых значений без ключей. Вы не можете вставить значение с помощью ключа, а числовые индексы будут "reset" от 0 до N-1.
$keys = array_keys($a);
$index = array_flip($keys);
$key = key($a); //current element
//or
$key = 'k1';
array_splice($a, $index[$key] + 1, 0, array('value'));
Ответ 6
Там хорошая функция, которая поможет вам здесь: https://gist.github.com/scribu/588429