Я ищу простую функцию для перемещения элемента массива в новую позицию в массиве и повторения индексов, чтобы в последовательности не было пробелов. Он не должен работать с ассоциативными массивами. У кого-нибудь есть идеи для этого?
$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']
Как прокомментировано, 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'];
Решение из 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']
Массивы в PHP не являются фактическим массивом в C-сенсе, а ассоциативными массивами. Но способ перемещения значения из индекса в другой является спокойным прямолинейным и тем же, что и в 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 )
Вам нужно будет добавить некоторую обработку Исключения, чтобы иметь полный код.
Я думаю, что вы ищете встроенную функцию 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"; } ?>
Может быть, я ошибаюсь, но не должно быть проще просто сделать копию массива, а затем заменить значения?
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);
Вам нужно создать вспомогательную переменную.
moveElement($a, $i,$j) { $k=$a[$i]; $a[$i]=$a[$j]; $a[$j]=$k; return $a; }
Взгляните на эту тему, которая описывает аналогичную проблему. Предусмотрено следующее решение:
/** * 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; }
Функция, которая сохраняет ключи:
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 )