【问题标题】:PHP: 'rotate' an array?PHP:“旋转”一个数组?
【发布时间】:2011-08-01 21:11:54
【问题描述】:

是否可以在 PHP 中轻松“旋转”数组?

像这样: 1, 2, 3, 4 -> 2, 3 ,4 ,1

是否有某种内置的 PHP 函数?

【问题讨论】:

  • 这里有一个提示:您需要做的就是删除第一个元素(“pop”),然后将其作为最后一个元素添加回来(“push”)。

标签: php arrays rotation shift


【解决方案1】:
  $numbers = array(1,2,3,4);
  array_push($numbers, array_shift($numbers));
  print_r($numbers);

输出

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
    [3] => 1
)

【讨论】:

  • 如果您只是像向量一样使用数组,并且索引值并不重要,这很好。但是,如果您有一个要旋转的关联数组,则此方法会破坏您的数组键。请参阅我的答案以了解如何保存它们。
  • @Cam,你说的完全正确,甚至 OP 也没有提到数组索引,只是值。您的答案对于正在寻找旋转数组元素的两个部分的解决方案的人很有价值。 (+1 为您的回答)
  • 是的,显然你的方法对于OP来说已经足够了,否则他不会接受的!但是,是的,我想我会添加我的答案,以防有人遇到和我一样的问题:)
  • 这就是我要找的东西!
  • 向右旋转:array_unshift($numbers,array_pop($numbers));
【解决方案2】:

大多数当前答案都是正确的,但前提是您不关心索引:

$arr = array('foo' => 'bar', 'baz' => 'qux', 'wibble' => 'wobble');
array_push($arr, array_shift($arr));
print_r($arr);

输出:

Array
(
    [baz] => qux
    [wibble] => wobble
    [0] => bar
)

要保留您的索引,您可以执行以下操作:

$arr = array('foo' => 'bar', 'baz' => 'qux', 'wibble' => 'wobble');

$keys = array_keys($arr);
$val = $arr[$keys[0]];
unset($arr[$keys[0]]);
$arr[$keys[0]] = $val;

print_r($arr);

输出:

Array
(
    [baz] => qux
    [wibble] => wobble
    [foo] => bar
)

也许有人可以比我的四行方法更简洁地进行轮换,但这仍然有效。

【讨论】:

  • 打高尔夫球:list($k,$v)=each($arr);unset($arr[$k]);$arr[$k]=$v;。您可能需要在前面加上 reset($arr);
【解决方案3】:

这非常简单,可以通过多种方式完成。示例:

$array   = array( 'a', 'b', 'c' );
$array[] = array_shift( $array );

【讨论】:

    【解决方案4】:

    循环遍历数组以及shift-ing 和push-ing 可能是旋转数组的常用方法,但它经常会弄乱您的键。更稳健的方法是使用array_mergearray_splice 的组合。

    /**
     * Rotates an array.
     * 
     * Numerical indexes will be renumbered automatically.
     * Associations will be kept for keys which are strings.
     * 
     * Rotations will always occur similar to shift and push,
     * where the number of items denoted by the distance are
     * removed from the start of the array and are appended.
     * 
     * Negative distances work in reverse, and are similar to
     * pop and unshift instead.
     * 
     * Distance magnitudes greater than the length of the array
     * can be interpreted as rotating an array more than a full
     * rotation. This will be reduced to calculate the remaining
     * rotation after all full rotations.
     * 
     * @param array $array The original array to rotate.
     * Passing a reference may cause the original array to be truncated.
     * @param int $distance The number of elements to move to the end.
     * Distance is automatically interpreted as an integer.
     * @return array The modified array.
     */
    function array_rotate($array, $distance = 1) {
        settype($array, 'array');
        $distance %= count($array);
        return array_merge(
            array_splice($array, $distance), // Last elements  - moved to the start
            $array                          //  First elements - appended to the end
        );
    }
    // Example rotating an array 180°.
    $rotated_180 = array_rotate($array, count($array) / 2);
    

    或者,如果您还发现需要旋转键以使它们与不同的值匹配,您可以组合 array_keysarray_combinearray_rotatearray_values

    /**
     * Rotates the keys of an array while keeping values in the same order.
     * 
     * @see array_rotate(); for function arguments and output.
     */
    function array_rotate_key($array, $distance = 1) {
        $keys = array_keys((array)$array);
        return array_combine(
            array_rotate($keys, $distance), // Rotated keys
            array_values((array)$array)    //  Values
        );
    }
    

    或者在保持键顺序相同的同时旋转值(相当于在匹配的array_rotate_key函数调用上调用负距离)。

    /**
     * Rotates the values of an array while keeping keys in the same order.
     * 
     * @see array_rotate(); for function arguments and output.
     */
    function array_rotate_value($array, $distance = 1) {
        $values = array_values((array)$array);
        return array_combine(
            array_keys((array)$array),        // Keys
            array_rotate($values, $distance) //  Rotated values
        );
    }
    

    最后,如果您想防止数字索引重新编号。

    /**
     * Rotates an array while keeping all key and value association.
     * 
     * @see array_rotate(); for function arguments and output.
     */
    function array_rotate_assoc($array, $distance = 1) {
        $keys = array_keys((array)$array);
        $values = array_values((array)$array);
        return array_combine(
            array_rotate($keys, $distance),   // Rotated keys
            array_rotate($values, $distance) //  Rotated values
        );
    }
    

    执行一些基准测试可能会有所帮助,但是,我希望每个请求的少量轮换不会显着影响性能,无论使用哪种方法。

    也应该可以使用自定义排序函数来旋转数组,但它很可能过于复杂。即usort

    【讨论】:

      【解决方案5】:

      一种维护键和旋转的方法。使用与 array_push(array, array_shift(array)) 相同的概念,而是使用 2 个 array_slices 的 array_merge

      $x = array("a" => 1, "b" => 2, "c" => 3, 'd' => 4);

      将第一个元素移动到末尾

      array_merge(array_slice($x, 1, NULL, true), array_slice($x, 0, 1, true) //'b'=>2, 'c'=>3, 'd'=>4, 'a'=>1

      将最后一个元素移到前面

      array_merge(array_slice($x, count($x) -1, 1, true), array_slice($x, 0, //'d'=>4, 'a'=>1, 'b'=>2, 'c'=>3

      【讨论】:

        【解决方案6】:

        你可以使用这个功能:

            function arr_rotate(&$array,$rotate_count) {
                for ($i = 0; $i < $rotate_count; $i++) {
                    array_push($array, array_shift($array));
                }
            }
        

        用法:

            $xarr = array('1','2','3','4','5');
            arr_rotate($xarr, 2);
            print_r($xarr);
        

        结果:

         Array ( [0] => 3 [1] => 4 [2] => 5 [3] => 1 [4] => 2 )
        

        【讨论】:

        • 不错的简洁函数,但我觉得可以通过确保循环次数不超过数组元素的次数来稍微改进它。例如arr_rotate($xarr, count($xarr)); 将具有相同顺序的结果。添加行$rotate_count %= count($array); 将确保最大迭代次数始终小于元素数。
        【解决方案7】:

        Hackerrank 上有一个关于数组旋转的任务:https://www.hackerrank.com/challenges/array-left-rotation/problem

        使用array_pusharray_shift 提出的解决方案将适用于除最后一个因超时而失败的所有测试用例。所以,array_pusharray_shift 不会给你最快的解决方案。

        这是更快的方法:

        function leftRotation(array $array, $n) {
           for ($i = 0; $i < $n; $i++) {
               $value = array[$i]; unset(array[$i]); array[] = $value;
           }
           return array;
        }
        

        【讨论】:

          【解决方案8】:

          使用array_shiftarray_push

          【讨论】:

            【解决方案9】:
            $daynamesArray = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
            array_push($daynamesArray, array_shift($daynamesArray)); //shift by one
            array_push($daynamesArray, array_shift($daynamesArray)); //shift by two
            print_r($daynamesArray);
            

            输出从“星期三”开始:

            Array ( [0] => Wednesday [1] => Thursday [2] => Friday [3] => Saturday [4] => Sunday [5] => Monday [6] => Tuesday 
            

            【讨论】:

              【解决方案10】:

              是的,这是我自己做的一个函数,其中 $A 是数组,$K 是要旋转数组的次数:

              function solution($A, $K) {
              
                for($i = 0; $i < $K; $i++): //we cycle $K
                  $arrayTemp = $A;
                  for($j = 0; $j < count($arrayTemp); $j++): // we cycle the array
                     if($j == count($arrayTemp) - 1) $A[0] = $arrayTemp[$j]; // we check for the last position
                     else $A[$j + 1] = $arrayTemp[$j]; // all but last position
                  endfor;
                endfor;
               return $A;
              
              }
              

              【讨论】:

                【解决方案11】:

                逻辑是交换元素。算法可能看起来像 -

                 for i = 0 to arrayLength - 1
                    swap( array[i], array[i+1] )     // Now array[i] has array[i+1] value and 
                                                     // array[i+1] has array[i] value.
                

                【讨论】:

                • @Dylan - 如果你想自己写一个,可以实现上面的逻辑。
                【解决方案12】:

                没有。查看array_shift 的文档及其相关功能,了解可用于编写的一些工具。甚至可能在该页面的 cmets 中实现了 array_rotate 函数。

                还值得阅读左侧边栏中列出的数组函数,以全面了解 PHP 中可用的数组函数。

                【讨论】:

                  【解决方案13】:

                  这是一个将数组(零索引数组)旋转到您想要的任何位置的函数:

                  function rotateArray($inputArray, $rotateIndex) {
                    if(isset($inputArray[$rotateIndex])) {
                      $startSlice = array_slice($inputArray, 0, $rotateIndex);
                      $endSlice = array_slice($inputArray, $rotateIndex);
                      return array_merge($endSlice, $startSlice);
                    }
                    return $inputArray;
                  }
                  
                  $testArray = [1,2,3,4,5,6];
                  $testRotates = [3, 5, 0, 101, -5];
                  
                  foreach($testRotates as $rotateIndex) {
                    print_r(rotateArray($testArray, $rotateIndex));
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-12-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多