Циклический просмотр массива и shift
-ing и push
-ing могут быть распространенным способом вращения массива, однако он часто может испортить ваши ключи.Более надежный метод заключается в использовании комбинации array_merge
и 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);
В качестве альтернативы, если вам также необходимо повернуть клавиши так, чтобы они совпадали с различными значениями, вы можете объединить array_keys
, array_combine
, array_rotate
и 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
);
}
Или альтернативное вращение значений при сохранении ключей в том же порядке (эквивалентно вызову отрицательного расстояния для соответствующего 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
.