Вставить новый элемент в массив в любой позиции в PHP


Ответы:


920

Вы можете найти это немного более интуитивным. Требуется только один вызов функции для 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

Если замена - только один элемент, нет необходимости помещать array () вокруг него, если только элемент не является самим массивом, объектом или NULL.


32
Странно, что такая базовая функциональность на самом деле является своего рода скрытой, поскольку основное назначение этой функции, как описано в документации, заключается в чем-то другом (замена содержимого в массивах). Да, это указано в разделе аргументов, но если вы просто сканируете описания функций, чтобы найти, что использовать для вставки в массивы, вы бы никогда не нашли его.
Махн

24
Просто сказать, что это не сохранит ключи в $insertedмассиве.
Mauris

6
Также в руководстве по PHP, пример № 1: php.net/manual/en/function.array-splice.php
marcovtwout

3
@JacerOmri это совершенно верно, оба утверждения верны. Вы можете передать значение любого типа, но оно может не вести себя одинаково для массива, объекта или нуля. Для скаляров приведение типов (array)$scalarэквивалентно array($scalar), но для массива, объекта или нуля оно будет проигнорировано (массив), преобразовано в массив (объект) или станет пустым массивом ( ноль
Лукас

2
@SunilPachlangia, adelval и другие: с многомерными массивами вам нужно заключить замену в массив, это задокументировано. Я все еще принес записку сюда, чтобы люди перестали совершать ошибку.
Феликс Ганьон-Гренье

47

Функция, которая может вставлять как целые, так и строковые позиции:

/**
 * @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)
        );
    }
}

Целочисленное использование:

$arr = ["one", "two", "three"];
array_insert(
    $arr,
    1,
    "one-half"
);
// ->
array (
  0 => 'one',
  1 => 'one-half',
  2 => 'two',
  3 => 'three',
)

Использование строки:

$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',
  ),
)

2
array_splice()Теряет ключи, а array_merge()не делает. Таким образом, результаты первой функции могут быть очень удивительными ... Тем более, что если у вас есть два элемента с одним и тем же ключом, сохраняется только значение последнего ...
Алексис Уилк

33
$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)

11
Использование +вместо array_mergeможет сохранить ключи
Mauris

1
Теперь я могу добавить больше элементов до ИНДЕКСА
Аббас


5

Нет встроенной функции PHP (которая мне известна), которая могла бы делать именно то, что вы просили.

Я написал 2 метода, которые, я считаю, подходят для цели:

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;
}

Хотя это быстрее и, вероятно, более эффективно использует память, это действительно подходит только тогда, когда нет необходимости поддерживать ключи массива.

Если вам нужно сохранить ключи, более подходящим будет следующее:

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;
}

1
Это отлично работает. Однако во втором примере в вашей функции insertBefore()вы должны возвращать $tmpArrayвместо $input.
Кристоф Фишер,

4

Основанный на отличном ответе @Halil, вот простая функция, как вставить новый элемент после определенного ключа, сохраняя целочисленные ключи:

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)
    );
} 

4

Если вы хотите сохранить ключи исходного массива, а также добавить массив с ключами, используйте следующую функцию:

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);
}

Пример звонка:

$array = insertArrayAtPosition($array, array('key' => 'Value'), 3);

3
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;
}

3

Вот что у меня сработало для ассоциативного массива:

/*
 * 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;
}

Источник функции - это сообщение в блоге . Есть также удобная функция для вставки ДО конкретной клавиши.


2

Это также рабочее решение:

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;
}

кредиты идут по адресу : http://binarykitten.com/php/52-php-insert-element-and-shift.html


2

если не уверены, то НЕ ИСПОЛЬЗУЙТЕ ЭТО :

$arr1 = $arr1 + $arr2;

ИЛИ

$arr1 += $arr2;

потому что с + оригинальный массив будет перезаписан. ( см. источник )


2

Решение от jay.lee идеально. Если вы хотите добавить элемент (ы) в многомерный массив, сначала добавьте одномерный массив, а затем замените его.

$original = (
[0] => Array
    (
        [title] => Speed
        [width] => 14
    )

[1] => Array
    (
        [title] => Date
        [width] => 18
    )

[2] => Array
    (
        [title] => Pineapple
        [width] => 30
     )
)

Добавление элемента в том же формате к этому массиву добавит все новые индексы массива как элементы, а не просто элемент.

$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

Примечание. При добавлении элементов непосредственно в многомерный массив с помощью array_splice все его индексы будут добавлены как элементы, а не только этот элемент.


2

Вы можете использовать это

foreach ($array as $key => $value) 
{
    if($key==1)
    {
        $new_array[]=$other_array;
    }   
    $new_array[]=$value;    
}

1

Обычно со скалярными значениями:

$elements = array('foo', ...);
array_splice($array, $position, $length, $elements);

Чтобы вставить один элемент массива в ваш массив, не забудьте обернуть массив в массив (так как это было скалярное значение!):

$element = array('key1'=>'value1');
$elements = array($element);
array_splice($array, $position, $length, $elements);

в противном случае все ключи массива будут добавляться по частям.


1

Подсказка для добавления элемента в начало массива :

$a = array('first', 'second');
$a[-1] = 'i am the new first element';

тогда:

foreach($a as $aelem)
    echo $a . ' ';
//returns first, second, i am...

но:

for ($i = -1; $i < count($a)-1; $i++)
     echo $a . ' ';
//returns i am as 1st element

13
Подсказка для добавления элемента в начале:array_unshift($a,'i am the new first element');

1

Попробуй это:

$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;
}

1
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;
}

Пример звонка:

$array = array_insert($array, 1, ['123', 'abc']);

0

Для вставки элементов в массив со строковыми ключами вы можете сделать что-то вроде этого:

/* 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); 
} 

2
почему нет $src = array_merge($array_head, $ins, $array_tail);?
cartbeforehorse
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.