Inserte un nuevo elemento en la matriz en cualquier posición en PHP


Respuestas:


920

Puede encontrar esto un poco más intuitivo. Solo requiere una llamada de función para 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

Si el reemplazo es solo un elemento, no es necesario poner una matriz () a su alrededor, a menos que el elemento sea una matriz en sí misma, un objeto o NULL.


32
Es extraño que una funcionalidad tan básica esté realmente oculta, ya que el objetivo principal de esta función, tal como se describe en la documentación, es algo diferente (reemplazar las cosas en las matrices). Sí, se señala en la sección de argumentos, pero si solo está escaneando descripciones de funciones para encontrar qué usar para insertar en matrices, nunca lo habría encontrado.
Mahn

24
Solo digo que esto no conservará las claves en la $insertedmatriz.
mauris

66
También en el manual de PHP, ejemplo # 1: php.net/manual/en/function.array-splice.php
marcovtwout

3
@JacerOmri tiene toda la razón, ambas declaraciones son válidas. Puede pasar un valor de cualquier tipo, pero puede que no se comporte igual para una matriz, un objeto o un valor nulo. Para los escalares, la conversión de tipos (array)$scalares equivalente a array($scalar), pero para una matriz, un objeto o un valor nulo, se ignorará (matriz), se convertirá en una matriz (objeto) o se convertirá en una matriz vacía (nula); consulte php.net / manual / es / ...
Lukas

2
@SunilPachlangia, adelval y otros: con matrices multidimensionales, debe envolver el reemplazo en una matriz, está documentado. Todavía traje la nota aquí para que la gente deje de cometer el error.
Félix Gagnon-Grenier

47

Una función que se puede insertar en las posiciones de entero y de cadena:

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

Uso de enteros:

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

Uso de cadenas:

$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
El array_splice()pierde las llaves, mientras array_merge()que no. Entonces, los resultados de la primera función pueden ser muy sorprendentes ... Especialmente porque si tiene dos elementos con la misma clave, solo se mantiene el valor de la última ...
Alexis Wilke

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
Usar en +lugar de array_mergeconservar las claves
mauris

1
Ahora puedo agregar más elementos antes de un ÍNDICE
Abbas

5

De esta manera puede insertar matrices:

function array_insert(&$array, $value, $index)
{
    return $array = array_merge(array_splice($array, max(0, $index - 1)), array($value), $array);
}

2
Esa función no guarda el orden en la matriz.
Daniel Petrovaliev

5

No hay una función nativa de PHP (que yo sepa) que pueda hacer exactamente lo que solicitó.

He escrito 2 métodos que creo que son adecuados para su propósito:

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

Si bien es más rápido y probablemente más eficiente con la memoria, esto solo es realmente adecuado cuando no es necesario mantener las claves de la matriz.

Si necesita mantener las claves, lo siguiente sería más adecuado;

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
Esto funciona bien Sin embargo, en el segundo ejemplo, en su función insertBefore(), debe regresar en $tmpArraylugar de $input.
Christoph Fischer

4

Basado en la excelente respuesta de @Halil, aquí hay una función simple de cómo insertar un nuevo elemento después de una clave específica, mientras se conservan las teclas enteras:

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

Si desea conservar las claves de la matriz inicial y también agregar una matriz que tenga claves, utilice la función a continuación:

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

Ejemplo de llamada:

$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

Esto es lo que funcionó para mí para la matriz asociativa:

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

La fuente de la función: esta publicación de blog . También hay una función práctica para insertar ANTES de una clave específica.


2

Esta también es una solución de trabajo:

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

los créditos van a: http://binarykitten.com/php/52-php-insert-element-and-shift.html


2

si no está seguro, NO USE ESTOS :

$arr1 = $arr1 + $arr2;

O

$arr1 += $arr2;

porque con + matriz original se sobrescribirá. ( ver fuente )


2

La solución de jay.lee es perfecta. En caso de que desee agregar elementos a una matriz multidimensional, primero agregue una matriz unidimensional y luego reemplácela.

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

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

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

Agregar un elemento en el mismo formato a esta matriz agregará todos los nuevos índices de matriz como elementos en lugar de solo elementos.

$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

Nota: Agregar elementos directamente a una matriz multidimensional con array_splice agregará todos sus índices como elementos en lugar de solo ese elemento.


2

Puedes usar esto

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

1

Normalmente, con valores escalares:

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

Para insertar un solo elemento de matriz en su matriz, no olvide envolver la matriz en una matriz (¡ya que era un valor escalar!):

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

de lo contrario, todas las claves de la matriz se agregarán pieza por pieza.


1

Sugerencia para agregar un elemento al comienzo de una matriz :

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

entonces:

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

pero:

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

13
Sugerencia para agregar un elemento al principio:array_unshift($a,'i am the new first element');

1

Prueba este:

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

Ejemplo de llamada:

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

0

Para insertar elementos en una matriz con teclas de cadena, puede hacer algo como esto:

/* 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
¿por qué no $src = array_merge($array_head, $ins, $array_tail);?
cartbeforehorse
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.