Представим себе, что у нас есть два массива:
$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')
после третьего элемента каждого массива. Как мне это сделать?
$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);
дает:
массив ( [zero] => 0 [one] => 1 [два] => 2 [my_key] => my_value [три] => 3 )
Для вашего первого массива используйте 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 array_insert($arr, $insert, $position) { $i = 0; foreach ($arr as $key => $value) { if ($i == $position) { foreach ($insert as $ikey => $ivalue) { $ret[$ikey] = $ivalue; } } $ret[$key] = $value; $i++; } return $ret; }
на самом деле не выглядит удобно, но он работает.
Вот простая функция, которую вы могли бы использовать. Просто подключите n play.
Это вставка по индексу, а не по значению.
вы можете передать массив или использовать тот, который вы уже объявили.
EDIT: более короткая версия:
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);//eg index=5, then slice will result elements [0-4] //add the value at the end of the temp array// at the insertion index eg 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 ur 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));
Недавно я написал функцию, чтобы сделать что-то похожее на то, как это звучит, как вы пытаетесь, это аналогичный подход к ответу 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 ()), но тогда ключи ваших вставленных массивов были бы потеряны. Вздох.
Эта функция поддерживает:
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 )
Более чистый подход (основанный на текучести использования и меньшем количестве кода).
/** * 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));
Я просто создал класс 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; }
Не так конкретно, как ответ Artefacto, но, основываясь на его использовании использования 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 ie 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; }
с/** * * 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; }
Простейшее решение, если вы хотите вставить (элемент или массив) после определенного ключа:
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 )