2011-04-08 43 views
14

¿es posible 'girar' fácilmente una matriz en PHP?PHP: 'rotar' una matriz?

De esta manera: 1, 2, 3, 4 -> 2, 3, 4, 1

¿Hay algún tipo de función integrada de PHP para esto?

+3

Aquí hay una pista: todo lo que tiene que hacer es eliminar el primer elemento ("pop") y agregarlo nuevamente como el último elemento ("push"). –

+0

posible duplicado de [Girar una lista] (http://stackoverflow.com/questions/5055418/rotating-a-list) –

Respuesta

16

La mayoría de las respuestas actuales son correctas, pero sólo si no se preocupan por sus índices:

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

de salida:

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

Para preservar su le índices puede hacer algo como:

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

Salida:

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

Tal vez alguien puede hacer la rotación más sucinta que mi método de cuatro líneas, pero esto funciona de todos modos.

20
$numbers = array(1,2,3,4); 
    array_push($numbers, array_shift($numbers)); 
    print_r($numbers); 

salida

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

Esto está bien si solo está usando su matriz como un vector, y los valores de índice no son importante. Pero si tiene una matriz asociativa que está tratando de rotar, este método arruina sus claves de matriz. Vea mi respuesta de una manera que los preserve. –

+0

@Cam, tiene toda la razón al respecto, incluso OP no ha mencionado el índice de matriz, solo valores. Su respuesta es valiosa para las personas que buscan una solución para rotar ambas partes de los elementos de la matriz. (+1 para su respuesta) – Wh1T3h4Ck5

+0

sí, claramente su método fue suficiente para el OP, de lo contrario, ¡no lo habría aceptado! Pero sí, pensé que agregaría mi respuesta en caso de que alguien tuviera el mismo problema que yo :) –

1

La lógica es intercambiar los elementos. Algoritmo puede parecerse -

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. 
+0

@Dylan - Si desea escribir uno para usted, puede implementar la lógica anterior. – Mahesh

0

Nº revise la documentación de array_shift y sus funciones relacionadas para algunas de las herramientas que puede utilizar para escribir uno. Incluso podría haber una función array_rotate implementada en los comentarios de esa página.

También vale la pena leer las funciones de matriz enumeradas en la barra lateral izquierda para obtener una comprensión completa de las funciones de matriz disponibles en PHP.

3

Es muy simple y se puede hacer de muchas maneras. Ejemplo:

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

Un método para mantener las teclas y girar.usando el mismo concepto que array_push (array, array_shift (array)), en lugar vamos a utilizar array_merge de 2 array_slices

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

para mover el primer elemento al final

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

Para mover el último elemento en la parte delantera

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

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

La salida comienza en "Miércoles":

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

puede utilizar esta función:

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

uso:

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

resultado:

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

Bonita función sucinta, pero creo que se puede mejorar un poco al garantizar que no esté dando vueltas más veces que la matriz tiene elementos. Por ejemplo, 'arr_rotate ($ xarr, count ($ xarr));' tendrá los resultados en el mismo orden. Al agregar la línea '$ rotate_count% = count ($ array);' se asegurará de que la cantidad máxima de iteraciones sea siempre menor que la cantidad de elementos. –

0

Hay una tarea sobre la rotación gama de Hackerrank: https://www.hackerrank.com/challenges/array-left-rotation/problem.

Y la solución propuesta con array_push y array_shift funcionará para todos los casos de prueba excepto la última, que falla debido al tiempo de espera. Por lo tanto, array_push y array_shift no le darán la solución más rápida.

Aquí es el enfoque más rápido:

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

bucle a través de la matriz, y shift -ing y push -ing, puede ser una forma común para girar una matriz, sin embargo, a menudo se pueden estropear sus llaves. Un método más robusto es usar una combinación de array_merge y 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); 

Alternativamente, si también se encuentra la necesidad de girar las llaves para que coincidan con valores diferentes, se pueden combinar array_keys, array_combine, array_rotate y 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 
    ); 
} 

O, alternativamente, la rotación de los valores, manteniendo las llaves en el mismo orden (equivalente a llamar a la distancia negativo en la búsqueda de una llamada array_rotate_key función).

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

Y, por último, si desea evitar la renumeración de índices numéricos.

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

Podría ser beneficioso realizar algunas pruebas de referencia, sin embargo, espero que un pequeño puñado de rotaciones por petición no afectaría el rendimiento notablemente independientemente de qué método se utiliza.

También debería ser posible girar una matriz mediante el uso de una función de clasificación personalizada, pero lo más probable es que sea demasiado complicado. es decir, usort.