Представим, что у нас есть два массива:
$array_1 = array(
'0' => 'zero',
'1' => 'one',
'2' => 'two',
'3' => 'three',
);
$array_2 = array(
'zero' => '0',
'one' => '1',
'two' => '2',
'three' => '3',
);
Теперь я хотел бы вставить array('sample_key' => 'sample_value')
после третьего элемента каждого массива. Как я могу это сделать?
Ответы:
array_slice()
может использоваться для извлечения частей массива, а оператор+
объединения массива ( ) может рекомбинировать части.$res = array_slice($array, 0, 3, true) + array("my_key" => "my_value") + array_slice($array, 3, count($array)-3, true);
Этот пример:
$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);
дает:
источник
+
не следует использовать! Используйтеarray_merge
вместо этого! BE потому что, если индексы являются целыми числами (нормальный массив, а не хеш),+
не будет работать должным образом !!!array_merge
поведение по отношению к цифровым клавишам не подходит для этого вопроса.count($array)-3
вы можете просто указать null с тем же эффектом. Кроме того, использованиеarray_merge
предложенного TMS не требует использования уникального индекса. ПРИМЕР: Добавить «новое значение» в существующий массив:$b = array_merge( array_slice( $a, 0, 1, true ), array( 'new-value' ), array_slice( $a, 1, null, true ) );
+
против прогнозаarray_merge
. Если вы хотите вставить что-то в числовой массив, вы не должны использовать+
его, потому что он, вероятно, не будет соответствовать вашим ожиданиям. Но выarray_merge
тоже не должны использовать ; для числовых массивов вся эта проблема решается с помощьюarray_splice
функции. Для ассоциативных или смешанных массивов вы, вероятно, не хотите переиндексировать числовые ключи, поэтому использование+
вполне уместно.Для вашего первого массива используйте
array_splice()
:$array_1 = array( '0' => 'zero', '1' => 'one', '2' => 'two', '3' => 'three', ); array_splice($array_1, 3, 0, 'more'); print_r($array_1);
выход:
Array( [0] => zero [1] => one [2] => two [3] => more [4] => three )
для второго заказа нет, поэтому вам просто нужно сделать:
$array_2['more'] = '2.5'; print_r($array_2);
И отсортируйте ключи по своему усмотрению.
источник
код:
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; }
пример:
$array = ["A"=8, "K"=>3]; $insert_array = ["D"= 9]; insertValueAtPosition($array, $insert_array, $position=2); // result ====> ["A"=>8, "D"=>9, "K"=>3];
Может выглядеть не идеально, но работает.
источник
Вот простая функция, которую вы могли бы использовать. Просто подключи и играй.
Это вставка по индексу, а не по значению.
вы можете передать массив или использовать тот, который вы уже объявили.
РЕДАКТИРОВАТЬ: более короткая версия:
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)); } }
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 }
Теперь вы можете протестировать код, используя
//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>";
И вот результат:
//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));
источник
Эта функция поддерживает:
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; }
ПРИМЕНЕНИЕ:
$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) );
ПОЛУЧЕННЫЕ РЕЗУЛЬТАТЫ:
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 )
источник
Недавно я написал функцию, которая делает что-то похожее на то, что вы пытаетесь сделать, это аналогичный подход к ответу clasvdb.
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; }
Обычно он вставляется в определенном месте, но избегает перезаписи, сдвигая все элементы вниз.
источник
Если вы не знаете, что хотите вставить его в позицию № 3, но знаете ключ , после которого хотите вставить его, я приготовил эту небольшую функцию, увидев этот вопрос.
/** * 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; }
Вот скрипт кодовой панели, чтобы увидеть его в действии: http://codepad.org/5WlKFKfz
Примечание: array_splice () был бы намного более эффективным, чем array_merge (array_slice ()), но тогда ключи ваших вставленных массивов были бы потеряны. Вздох.
источник
Более чистый подход (основанный на плавности использования и меньшем количестве кода).
/** * 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; }
Применение:
$colors = [ 'blue' => 'Blue', 'green' => 'Green', 'orange' => 'Orange', ]; $colors = array_insert($colors, 'blue', 'pink', 'Pink'); die(var_dump($colors));
источник
Самое простое решение, если вы хотите вставить (элемент или массив) после определенного ключа:
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; }
Итак, если у вас есть:
$array = [ 'one' => 1, 'three' => 3 ]; $array_to_insert = ['two' => 2];
И выполните:
$result_array = array_splice_after_key($array, 'one', $array_to_insert);
У вас будет:
Array ( ['one'] => 1 ['two'] => 2 ['three'] => 3 )
источник
Использование array_splice вместо array_slice дает на один вызов функции меньше.
$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);
источник
Я делаю это как
$slightly_damaged = array_merge( array_slice($slightly_damaged, 0, 4, true) + ["4" => "0.0"], array_slice($slightly_damaged, 4, count($slightly_damaged) - 4, true) );
источник
Я только что создал класс ArrayHelper, который упростил бы это для числовых индексов.
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(); } } }
Пример:
$array = array('a', 'b', 'c', 'd', 'e'); $insertValue = 'insert'; \ArrayHelper::insertValueAtPos($array, 3, $insertValue);
Начало массива $:
Array ( [0] => a [1] => b [2] => c [3] => d [4] => e )
Результат:
Array ( [0] => a [1] => b [2] => c [3] => insert [4] => d [5] => e )
источник
Это лучший способ вставить элемент в массив в какую-либо позицию.
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; }
источник
Мне нужно было что-то, что могло бы делать вставку до, замену, после ключа; и добавьте в начало или конец массива, если целевой ключ не найден. По умолчанию вставляется после ключа.
Новая функция
/** * 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; }
Введите код
$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);
Выход
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 )
источник
Очень простой двухстрочный ответ на ваш вопрос:
$array_1 = array( '0' => 'zero', '1' => 'one', '2' => 'two', '3' => 'three', );
Сначала вы вставляете что-либо в свой третий элемент с помощью array_splice, а затем присваиваете значение этому элементу:
array_splice($array_1, 3, 0 , true); $array_1[3] = array('sample_key' => 'sample_value');
источник
Это старый вопрос, но я опубликовал комментарий в 2014 году и часто к нему возвращаюсь. Думал оставлю полный ответ. Это не самое короткое решение, но его довольно легко понять.
Вставьте новое значение в ассоциативный массив в пронумерованной позиции, сохраняя ключи и сохраняя порядок.
$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 ) */
источник
Это еще одно решение в
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) ); }
источник
Не такой конкретный, как ответ Артефакто, но, основываясь на его предложении об использовании array_slice (), я написал следующую функцию:
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); }
Особенности:
Примеры использования:
$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));
источник
Если вы просто хотите вставить элемент в массив в определенной позиции (на основе ответа @clausvdb):
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; }
источник
Вот моя версия:
/** * * 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; }
источник
Вы можете вставлять элементы во время цикла foreach , поскольку этот цикл работает с копией исходного массива, но вы должны отслеживать количество вставленных строк (я называю это «раздуванием» в этом коде):
$bloat=0; foreach ($Lines as $n=>$Line) { if (MustInsertLineHere($Line)) { array_splice($Lines,$n+$bloat,0,"string to insert"); ++$bloat; } }
Очевидно, вы можете обобщить эту «раздутую» идею для обработки произвольных вставок и удалений во время цикла foreach.
источник
легкий способ .. используя
array_splice()
$array_1 = array( '0' => 'zero', '1' => 'one', '2' => 'two', '3' => 'three', ); $addArray = array('sample_key' => 'sample_value'); array_splice($rs, 3, 0, $addArray);
Результат ..
Array ( [0] => zero [1] => one [2] => two [3] => sample_value [4] => three )
источник