2012-09-27 94 views
28

我正在寻找一个简单的函数来将数组元素移动到数组中的新位置,并对索引进行重新排序,以便序列中没有间隔。它不需要使用关联数组。任何人都有这个想法吗?将数组元素移动到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'] 
+5

请添加示例和预期的行为..还有,你有什么尝试? –

+0

一些代码与预期的结果将有助于... – Baba

+0

你在寻找'array_values'? – Gordon

回答

73

至于评论,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']; 
+0

是的,它是很好很简单的解决方案,但它只有在旧索引大于新索引时才有效。这是另一个解决方案:[link](http://stackoverflow.com/questions/9212312/moving-up-down-an-item-in-the-array-by-its-value) – quarky

+2

@quarky:不,它如果新索引大于旧索引,也可以工作。如果两者都是相同的。 – hakre

+4

但是,如果您的目的地是在源之后,它可能不会将它放在您预测的位置,因为在第一步之后数组变短。如果移动到最后,你不想使用size-1,你想要size-2 –

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"; 
} 
?> 
+0

那么,'usort'与你的回调和只是'sort()'有什么区别?这又是如何解决这个问题的? – KingCrunch

+0

没有什么区别,它只是在那里演示功能的用法。 – soulmerge

0

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

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

这更像是'swapElements()',但不会移动 – KingCrunch

+0

从他的例子看来,他正在尝试...... –

+0

否:'c'将会转到'3'而不是'2',就像这个例子。 – KingCrunch

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

你需要添加一些异常处理有一个完整的代码。

0

,保留键A的功能:

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

从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'] 
+0

苹果是索引1和番茄索引3.在您的结果番茄现在是1和苹果现在索引4,而是坚果是索引3.那么这个解决方案究竟是如何呢? – 2017-05-22 00:40:07

+0

你必须从0开始计数。苹果在位置1,它被移动到位置3 – RubbelDeCatc

+0

你换了1,3。 **之前:(1 =苹果,3 =坚果),你得到后**:1 =西红柿3 =苹果。这不是交换,它只是将苹果移动到正确的索引(3),而不是坚果为1,现在西红柿为1。 – 2017-05-24 14:37:38

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

这样你只交换两个元素但是任务是移动 – RubbelDeCatc