将数组元素移动到PHP中的新索引

时间:2012-09-27 14:50:03

标签: php arrays

我正在寻找一个简单的函数来将数组元素移动到数组中的新位置并重新排序索引,以便序列中没有间隙。它不需要使用关联数组。有人有这个想法吗?

$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' ]

10 个答案:

答案 0 :(得分:93)

评论时,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',
];

答案 1 :(得分:6)

带有两个array_splice命令的hakre解决方案不适用于命名数组。移动元素的键将丢失。

相反,您可以将数组拼接两次并合并各个部分。

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']

答案 2 :(得分:2)

PHP中的数组不是C sens中的实际数组,而是关联数组。 但是将值从索引移动到另一个索引的方法很简单,并且与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
)

您需要添加一些异常处理才能获得完整的代码。

答案 3 :(得分: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";
}
?>

答案 4 :(得分:1)

可能我错了,但是不应该只是复制数组然后替换值?

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

答案 5 :(得分:1)

很多好的答案。这是一个简单的@RubbelDeCatc的答案。这样做的好处是,您只需要知道数组键,而不必知道它的当前位置(在重新定位之前)。

/**
 * Reposition an array element by its key.
 *
 * @param array      $array The array being reordered.
 * @param string|int $key They key of the element you want to reposition.
 * @param int        $order The position in the array you want to move the element to. (0 is first)
 *
 * @throws \Exception
 */
function repositionArrayElement(array &$array, $key, int $order): void
{
    if(($a = array_search($key, array_keys($array))) === false){
        throw new \Exception("The {$key} cannot be found in the given array.");
    }
    $p1 = array_splice($array, $a, 1);
    $p2 = array_splice($array, 0, $order);
    $array = array_merge($p2, $p1, $array);
}

直接使用:

$fruits = [
    'bananas'=>'12', 
    'apples'=>'23',
    'tomatoes'=>'21', 
    'nuts'=>'22',
    'foo'=>'a',
    'bar'=>'b'
];

repositionArrayElement($fruits, "foo", 1);

var_export($fruits);

/** Returns
array (
  'bananas' => '12',
  'foo' => 'a', <--  Now moved to position #1
  'apples' => '23',
  'tomatoes' => '21',
  'nuts' => '22',
  'bar' => 'b',
)
**/

还可以处理数字数组:

$colours = ["green", "blue", "red"];

repositionArrayElement($colours, 2, 0);

var_export($colours);

/** Returns
array (
  0 => 'red', <-- Now moved to position #0
  1 => 'green',
  2 => 'blue',
)
*/

Demo

答案 6 :(得分:0)

您需要创建一个辅助变量。

moveElement($a, $i,$j)
  {
  $k=$a[$i];
  $a[$i]=$a[$j];
  $a[$j]=$k;
  return $a;
  }

答案 7 :(得分:0)

查看描述类似问题的this主题。提供以下解决方案:

/**
 * 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 :(得分:0)

保留键的功能:

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

输出:

Array
(
    [0] => a
    [1] => d
    [2] => b
    [3] => c
    [4] => e
)
Array
(
    [A] => a
    [D] => d
    [B] => b
    [C] => c
    [E] => e
)

答案 9 :(得分:0)

基于a previous answer。如果需要保存关联数组的键索引,可以是任何数字或字符串:

function custom_splice(&$ar, $a, $b){
    $out = array_splice($ar, $a, 1);
    array_splice($ar, $b, 0, $out);
}

function moveElement(&$array, $a, $b) {
    $keys = array_keys($array);

    custom_splice($array, $a, $b);
    custom_splice($keys, $a, $b); 

    $array = array_combine($keys,$array);
}
$s = '{ 
"21": "b", 
"2": "2", 
"3": "3", 
"4": "4", 
"6": "5", 
"7": "6" 
}';
$e = json_decode($s,true);

moveElement($e, 2, 0); 

print_r($e);

Array
(
    [3] => 3
    [21] => b
    [2] => 2
    [4] => 4
    [6] => 5
    [7] => 6
)

Demo

A previous answer破坏了数字索引-使它们从0开始。