Je recherche une fonction simple permettant de déplacer un élément de tableau à une nouvelle position dans le tableau et de reséquencer les index afin qu'il n'y ait pas de lacunes dans la séquence. Il n'est pas nécessaire de travailler avec des tableaux associatifs. Quelqu'un a des idées pour celui-ci?
$a = array(
0 => 'a',
1 => 'c',
2 => 'd',
3 => 'b',
4 => 'e',
);
print_r(moveElement(3,1))
//should output
[ 0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd',
4 => 'e' ]
Comme indiqué, 2x array_splice
, il n'est même pas nécessaire de renuméroter:
$array = [
0 => 'a',
1 => 'c',
2 => 'd',
3 => 'b',
4 => 'e',
];
function moveElement(&$array, $a, $b) {
$out = array_splice($array, $a, 1);
array_splice($array, $b, 0, $out);
}
moveElement($array, 3, 1);
Résultat:
[
0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd',
4 => 'e',
];
La solution de hakre avec deux commandes array_splice ne fonctionne pas avec les tableaux nommés. La clé de l'élément déplacé sera perdue.
Au lieu de cela, vous pouvez assembler le tableau deux fois et fusionner les parties.
function moveElement(&$array, $a, $b) {
$p1 = array_splice($array, $a, 1);
$p2 = array_splice($array, 0, $b);
$array = array_merge($p2,$p1,$array);
}
Comment ça marche:
Exemple:
$fruits = array(
'bananas'=>'12',
'apples'=>'23',
'tomatoes'=>'21',
'nuts'=>'22',
'foo'=>'a',
'bar'=>'b'
);
moveElement($fruits, 1, 3);
// Result
['bananas'=>'12', 'tomatoes'=>'21', 'nuts'=>'22', 'apples'=>'23', 'foo'=>'a', 'bar'=>'b']
Les tableaux dans PHP ne sont pas des tableaux réels dans le sens C, mais des tableaux associatifs . Mais la manière de déplacer une valeur d'un index à un autre est assez simple et est identique à celle de C++:
Copiez la valeur à déplacer dans un tampon temporaire, convertissez tous les éléments pour écraser le point vide à la position source et libérez ainsi un point sur la position de destination . Placez la valeur de sauvegarde dans le point de destination.
function moveElement ($a , $i , $j)
{
$tmp = $a[$i];
if ($i > $j)
{
for ($k = $i; $k > $j; $k--) {
$a[$k] = $a[$k-1];
}
}
else
{
for ($k = $i; $k < $j; $k++) {
$a[$k] = $a[$k+1];
}
}
$a[$j] = $tmp;
return $a;
}
$a = array(0, 1, 2, 3, 4, 5);
print_r($a);
$a = moveElement($a, 1, 4);
echo ('1 -> 4');
print_r($a);
$a = moveElement($a, 5, 0);
echo ('5 -> 0' );
print_r($a);
Sortie:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
)
1 -> 4Array
(
[0] => 0
[1] => 2
[2] => 3
[3] => 4
[4] => 1
[5] => 5
)
5 -> 0Array
(
[0] => 5
[1] => 0
[2] => 2
[3] => 3
[4] => 4
[5] => 1
)
Vous aurez besoin d'ajouter un peu de gestion des exceptions pour avoir un code complet.
Peut-être que je me trompe, mais ne devrait-il pas être plus simple de copier le tableau, puis de remplacer les valeurs?
function swap($input, $a, $b){
$output = $input;
$output[$a] = $input[$b];
$output[$b] = $input[$a];
return $output;
}
$array = ['a', 'c', 'b'];
$array = swap($array, 1, 2);
Je pense que vous recherchez la fonction intégrée usort . Exemple tiré de la page de référence liée:
<?php
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
?>
Une fonction qui conserve les clés:
function moveElementInArray($array, $toMove, $targetIndex) {
if (is_int($toMove)) {
$tmp = array_splice($array, $toMove, 1);
array_splice($array, $targetIndex, 0, $tmp);
$output = $array;
}
elseif (is_string($toMove)) {
$indexToMove = array_search($toMove, array_keys($array));
$itemToMove = $array[$toMove];
array_splice($array, $indexToMove, 1);
$i = 0;
$output = Array();
foreach($array as $key => $item) {
if ($i == $targetIndex) {
$output[$toMove] = $itemToMove;
}
$output[$key] = $item;
$i++;
}
}
return $output;
}
$arr1 = Array('a', 'b', 'c', 'd', 'e');
$arr2 = Array('A' => 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e');
print_r(moveElementInArray($arr1, 3, 1));
print_r(moveElementInArray($arr2, 'D', 1));
Sortie:
Array
(
[0] => a
[1] => d
[2] => b
[3] => c
[4] => e
)
Array
(
[A] => a
[D] => d
[B] => b
[C] => c
[E] => e
)
Jetez un coup d'œil à this thread qui décrit un problème similaire. La solution suivante est fournie:
/**
* Move array element by index. Only works with zero-based,
* contiguously-indexed arrays
*
* @param array $array
* @param integer $from Use NULL when you want to move the last element
* @param integer $to New index for moved element. Use NULL to Push
*
* @throws Exception
*
* @return array Newly re-ordered array
*/
function moveValueByIndex( array $array, $from=null, $to=null )
{
if ( null === $from )
{
$from = count( $array ) - 1;
}
if ( !isset( $array[$from] ) )
{
throw new Exception( "Offset $from does not exist" );
}
if ( array_keys( $array ) != range( 0, count( $array ) - 1 ) )
{
throw new Exception( "Invalid array keys" );
}
$value = $array[$from];
unset( $array[$from] );
if ( null === $to )
{
array_Push( $array, $value );
} else {
$tail = array_splice( $array, $to );
array_Push( $array, $value );
$array = array_merge( $array, $tail );
}
return $array;
}
Vous devez créer une variable auxiliaire.
moveElement($a, $i,$j)
{
$k=$a[$i];
$a[$i]=$a[$j];
$a[$j]=$k;
return $a;
}