Переместить элемент массива в новый индекс в PHP
Я ищу простую функцию, чтобы переместить элемент массива на новую позицию в массиве и повторно упорядочить индексы, чтобы в последовательности не было пробелов. Не нужно работать с ассоциативными массивами. У кого-нибудь есть идеи для этого?
$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' ]
Ответы
Ответ 1
Как прокомментировано, 2x array_splice
, нет нужды даже перенумеровывать:
$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);
Результат:
[
0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd',
4 => 'e',
];
Ответ 2
Решение из hakre с двумя командами array_splice не работает с именованными массивами. Ключ перемещенного элемента будет потерян.
Вместо этого вы можете сращивать массив два раза и объединить части.
function moveElement(&$array, $a, $b) {
$p1 = array_splice($array, $a, 1);
$p2 = array_splice($array, 0, $b);
$array = array_merge($p2,$p1,$array);
}
Как это работает:
- Сначала: удалить/соединить элемент из массива
- Во-вторых: сплайсируйте массив на две части в позиции, в которую вы хотите вставить элемент
- Объедините три части вместе
Пример:
$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']
Ответ 3
Массивы в PHP не являются фактическим массивом в C-сенсе, а ассоциативными массивами.
Но способ перемещения значения из индекса в другой является спокойным прямолинейным и тем же, что и в С++:
Скопируйте значение, чтобы переместиться во временный буфер, переведите все элементы, чтобы раздавить пустое место в исходной позиции и в том же самом свободном месте в месте назначения.
Поместите резервное значение в место назначения.
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);
Вывод:
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
)
Вам нужно добавить некоторую обработку Исключения, чтобы иметь полный код.
Ответ 4
Я думаю, что вы ищете встроенную функцию usort. Пример со страницы ссылки:
<?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";
}
?>
Ответ 5
Может быть, я ошибаюсь, но не проще ли просто сделать копию массива, а затем заменить значения?
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);
Ответ 6
Вам нужно создать вспомогательную переменную.
moveElement($a, $i,$j)
{
$k=$a[$i];
$a[$i]=$a[$j];
$a[$j]=$k;
return $a;
}
Ответ 7
Взгляните на этот поток, который описывает аналогичную проблему. Предусмотрено следующее решение:
/**
* 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;
}
Ответ 8
Функция, которая сохраняет ключи:
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));
Ouput:
Array
(
[0] => a
[1] => d
[2] => b
[3] => c
[4] => e
)
Array
(
[A] => a
[D] => d
[B] => b
[C] => c
[E] => e
)