PHP: 'rotate' an array?

后端 未结 14 1661
小鲜肉
小鲜肉 2020-11-28 14:16

is it possible to easily \'rotate\' an array in PHP ?

Like this: 1, 2, 3, 4 -> 2, 3 ,4 ,1

Is there some kind of built-in PHP function for this?

相关标签:
14条回答
  • 2020-11-28 14:43

    Looping through the array, and shift-ing and push-ing, may be a common way to rotate an array, however it can often mess up your keys. A more robust method is using a combination of array_merge and array_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);
    

    Alternatively, if you also find the need to rotate keys so that they match with different values, you can combine array_keys, array_combine, array_rotate, and array_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
        );
    }
    

    Or alternatively rotating the values while keeping the keys in the same order (equivalent to calling the negative distance on the matching array_rotate_key function call).

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

    And finally, if you want to prevent renumbering of numerical indexes.

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

    It could be beneficial to perform some benchmark tests, however, I expect that a small handful of rotations per request wouldn't affect performance noticeably regardless of which method is used.

    It should also be possible to rotate an array by using a custom sorting function, but it would most likely be overly complicated. i.e. usort.

    0 讨论(0)
  • 2020-11-28 14:43

    Yes it is, here is a function I did myself, where $A is the array and $K the number of times you want to rotate the array:

    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;
    
    }
    
    0 讨论(0)
  • 2020-11-28 14:51

    It's very simple and could be done in many ways. Example:

    $array   = array( 'a', 'b', 'c' );
    $array[] = array_shift( $array );
    
    0 讨论(0)
  • 2020-11-28 14:53

    Here's a function to rotate an array (zero-indexed array) to any position you want:

    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));
    }
    
    0 讨论(0)
  • 2020-11-28 14:56

    A method to maintain keys and rotate. using the same concept as array_push(array, array_shift(array)), instead we will use array_merge of 2 array_slices

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

    To move the First element to the end

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

    To move the last element to the front

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

    0 讨论(0)
  • 2020-11-28 14:57
    $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);
    

    The output starts at "Wednesday":

    Array ( [0] => Wednesday [1] => Thursday [2] => Friday [3] => Saturday [4] => Sunday [5] => Monday [6] => Tuesday 
    
    0 讨论(0)
提交回复
热议问题