Insérer un nouvel élément dans le tableau à n'importe quelle position en PHP

Réponses:

920

Vous pouvez trouver cela un peu plus intuitif. Il ne nécessite qu'un seul appel de fonction pour 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 le remplacement n'est qu'un élément, il n'est pas nécessaire de mettre array () autour de lui, sauf si l'élément est un tableau lui-même, un objet ou NULL.

jay.lee
la source
32
Il est étrange qu'une telle fonctionnalité de base soit en quelque sorte cachée, en ce sens que l'objectif principal de cette fonction, comme décrit dans la documentation, est quelque chose de différent (remplacer les éléments dans les tableaux). Oui, cela est indiqué dans la section des arguments, mais si vous analysez simplement les descriptions de fonction pour trouver ce qu'il faut utiliser pour insérer dans les tableaux, vous ne l'avez jamais trouvé.
Mahn
24
Je dis simplement que cela ne préservera pas les clés du $insertedtableau.
mauris
6
Également dans le manuel PHP, exemple # 1: php.net/manual/en/function.array-splice.php
marcovtwout
3
@JacerOmri c'est tout à fait raison, les deux déclarations sont valides. Vous pouvez transmettre une valeur de n'importe quel type, mais elle peut ne pas se comporter de la même manière pour un tableau, un objet ou null. Pour les scalaires, la conversion de type (array)$scalaréquivaut à array($scalar), mais pour un tableau, un objet ou null, elle sera ignorée (tableau), convertie en tableau (objet) ou devenant un tableau vide (null) - voir php.net / manual / fr /…
Lukas
2
@SunilPachlangia, adelval et autres: avec les tableaux multidimensionnels, vous devez envelopper le remplacement dans un tableau, c'est documenté. J'ai quand même apporté la note ici pour que les gens cessent de faire l'erreur.
Félix Gagnon-Grenier
47

Une fonction qui peut insérer à la fois des positions entières et des chaînes:

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

Utilisation entière:

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

Utilisation des chaînes:

$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',
  ),
)
Halil Özgür
la source
2
Le array_splice()perd les clés, alors array_merge()que non. Ainsi, les résultats de la première fonction peuvent être très surprenants ... Surtout parce que si vous avez deux éléments avec la même touche, seule la valeur de la dernière est conservée ...
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)
ambre
la source
11
Utiliser +au lieu de array_mergepeut conserver les clés
mauris
1
Maintenant, je peux ajouter plus d'éléments avant un INDEX
Abbas
5

De cette façon, vous pouvez insérer des tableaux:

function array_insert(&$array, $value, $index)
{
    return $array = array_merge(array_splice($array, max(0, $index - 1)), array($value), $array);
}
Aleksandr Makov
la source
2
Cette fonction n'enregistre pas l'ordre dans le tableau.
Daniel Petrovaliev
5

Il n'y a pas de fonction PHP native (à ma connaissance) qui puisse faire exactement ce que vous avez demandé.

J'ai écrit 2 méthodes qui, selon moi, sont adaptées à l'objectif:

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

Bien que plus rapide et probablement plus efficace en mémoire, cela ne convient vraiment que lorsqu'il n'est pas nécessaire de conserver les clés du tableau.

Si vous avez besoin de conserver les clés, ce qui suit serait plus approprié;

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;
}
Un garçon nommé Su
la source
1
Cela fonctionne bien. Cependant, dans le deuxième exemple, dans votre fonction insertBefore(), vous devez retourner $tmpArrayau lieu de $input.
Christoph Fischer du
4

Basé sur @Halil une excellente réponse, voici une fonction simple pour insérer un nouvel élément après une clé spécifique, tout en préservant les clés entières:

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)
    );
} 
d.raev
la source
4

Si vous souhaitez conserver les clés du tableau initial et également ajouter un tableau contenant des clés, utilisez la fonction ci-dessous:

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

Exemple d'appel:

$array = insertArrayAtPosition($array, array('key' => 'Value'), 3);
Mayra M
la source
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;
}
Henry wong
la source
3

C'est ce qui a fonctionné pour moi pour le tableau associatif:

/*
 * 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 source de la fonction - cet article de blog . Il y a aussi une fonction pratique pour insérer une touche spécifique AVANT.

Oksana Romaniv
la source
2

C'est aussi une solution de travail:

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

les crédits vont à: http://binarykitten.com/php/52-php-insert-element-and-shift.html

Mike Doh
la source
2

en cas de doute, alors NE PAS UTILISER CES :

$arr1 = $arr1 + $arr2;

OU

$arr1 += $arr2;

car avec + le tableau d'origine sera écrasé. ( voir source )

T.Todua
la source
2

La solution de jay.lee est parfaite. Si vous souhaitez ajouter des éléments à un tableau multidimensionnel, ajoutez d'abord un tableau unidimensionnel, puis remplacez-le ensuite.

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

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

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

L'ajout d'un élément au même format à ce tableau ajoutera tous les nouveaux index de tableau en tant qu'éléments au lieu d'un seul élément.

$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

Remarque: l' ajout d'éléments directement à un tableau multidimensionnel avec array_splice ajoutera tous ses index en tant qu'éléments au lieu de cet élément uniquement.

Abdul Mannan
la source
2

Vous pouvez utiliser ceci

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

Normalement, avec des valeurs scalaires:

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

Pour insérer un seul élément de tableau dans votre tableau, n'oubliez pas d'envelopper le tableau dans un tableau (car c'était une valeur scalaire!):

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

sinon toutes les clés du tableau seront ajoutées pièce par pièce.

marque
la source
1

Astuce pour ajouter un élément au début d'un tableau :

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

puis:

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

mais:

for ($i = -1; $i < count($a)-1; $i++)
     echo $a . ' ';
//returns i am as 1st element
forsberg
la source
13
Astuce pour ajouter un élément au début:array_unshift($a,'i am the new first element');
1

Essaye celui-là:

$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;
}
Max
la source
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;
}

Exemple d'appel:

$array = array_insert($array, 1, ['123', 'abc']);
xayer
la source
0

Pour insérer des éléments dans un tableau avec des clés de chaîne, vous pouvez faire quelque chose comme ceci:

/* 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); 
} 
Bryan Plasters
la source
2
pourquoi pas $src = array_merge($array_head, $ins, $array_tail);?
cartbeforehorse