2012-07-01 16 views
6

En php, me gustaría tener la capacidad de reordenar una matriz asociativa moviendo elementos a ciertas posiciones en la matriz. No es necesario un tipo, solo un reordenamiento de mi elección.PHP: arreglo asociativo de orden re

Como ejemplo, decir que tengo una matriz asociativa como sigue:

array(
'a' => 'Element A', 
'b' => 'Element B', 
'c' => 'Element C', 
); 

y en un caso i posible que desee mover C antes de B y tienen el siguiente resultado:

array(
'a' => 'Element A', 
'c' => 'Element C', 
'b' => 'Element B', 
); 

o en otro caso, es posible que desee mover C antes de A y tenga el siguiente resultado:

array(
'c' => 'Element C', 
'a' => 'Element A', 
'b' => 'Element B', 
); 

Lo que estoy tratando de mostrar , es simplemente un método para decir "Oye, quiero mover este elemento de matriz antes que este otro elemento de matriz" o "Oye, id como mover este elemento de matriz para asegurarte de que viene después de este otro elemento de matriz"

Espero que esto tenga sentido!

gracias a cualquier persona con antelación a quién le importa que me ayude con este

+1

Las matrices asociativas no tienen ningún pedido. – DonCallisto

+13

@DonCallisto: Eso es totalmente falso. Las matrices también son listas, y como tales definitivamente tienen un orden bien definido. – Jon

+0

posible duplicado de [Sort array usando otra matriz] (http://stackoverflow.com/questions/8935093/sort-array-using-another-array) – nickb

Respuesta

2

Si se refiere a intercambiar dos valores se puede hacer una función como esta:

function array_swap($key1, $key2, $array) { 
     $newArray = array(); 
     foreach ($array as $key => $value) { 
      if ($key == $key1) { 
       $newArray[$key2] = $array[$key2]; 
      } elseif ($key == $key2) { 
       $newArray[$key1] = $array[$key1]; 
      } else { 
       $newArray[$key] = $value; 
      } 
     } 
     return $newArray; 
    } 
+1

Gracias por la respuesta, pero también necesito mover las teclas, no solo los valores –

+0

Ahora pruebe la nueva función –

8

Para una clasificación personalizada, puede, por ejemplo, crear una matriz que es el orden deseado de las teclas y luego asociar los valores con ellos. Ejemplo:

$input = array("a"=>"Element A","b"=>"Element B","c"=>"Element C"); 
$order = array("c","a","b"); 
$out = array(); 
foreach($order as $k) { 
    $out[$k] = $input[$k]; 
} 

Los elementos en $out estará en el orden especificado.

+0

Esto no funcionaría para mi problema. Necesito mover un elemento a antes o después de otro elemento. Así que mi método solo recibirá las dos claves –

0

array_splice por desgracia no funciona con matrices asociativas, así que aquí está algo un poco más desordenado:

$keys = array_keys($arr); 
$values = array_values($arr); 

$keyIndex = array_search($someKey, $keys); 
array_splice($keys, $keyIndex, 1); 
array_splice($values, $keyIndex, 1); 

$insertIndex = 1; 
array_splice($keys, $insertIndex, 0, array($someKey)); 
array_splice($values, $insertIndex, 0, array($arr[$someKey])); 

$arr = array_combine($keys, $values); 
7
$arr = array(
    'a' => 1, 
    'b' => 2, 
    'move me' => 9, 
    'c' => 3, 
    'd' => 4, 
); 

Oye, quiero mover ['moverme'] antes de ['b']. ¡Puedo hacerlo con solo 4 líneas de código!

$i = 0; foreach($arr as &$val) $val = array('sort' => (++$i * 10), 'val' => $val); 
$arr['move me']['sort'] = $arr['b']['sort'] - 5; 
uasort($arr, function($a, $b) { return $a['sort'] > $b['sort']; }); 
foreach($arr as &$val) $val = $val['val']; 




Hice una función para un fácil uso:

function move_item(&$ref_arr, $key1, $move, $key2 = null) 
{ 
    $arr = $ref_arr; 
    if($key2 == null) $key2 = $key1; 
    if(!isset($arr[$key1]) || !isset($arr[$key2])) return false; 

    $i = 0; foreach($arr as &$val) $val = array('sort' => (++$i * 10), 'val' => $val); 

    if(is_numeric($move)) 
    { 
    if($move == 0 && $key1 == $key2) return true; 
    elseif($move == 0) { $tmp = $arr[$key1]['sort']; $arr[$key1]['sort'] = $arr[$key2]['sort']; $arr[$key2]['sort'] = $tmp; } 
    else $arr[$key1]['sort'] = $arr[$key2]['sort'] + ($move * 10 + ($key1 == $key2 ? ($move < 0 ? -5 : 5) : 0)); 
    } 
    else 
    { 
    switch($move) 
    { 
     case 'up':  $arr[$key1]['sort'] = $arr[$key2]['sort'] - ($key1 == $key2 ? 15 : 5); break; 
     case 'down': $arr[$key1]['sort'] = $arr[$key2]['sort'] + ($key1 == $key2 ? 15 : 5); break; 
     case 'top': $arr[$key1]['sort'] = 5; break; 
     case 'bottom': $arr[$key1]['sort'] = $i * 10 + 5; break; 
     default: return false; 
    } 
    } 
    uasort($arr, function($a, $b) { return $a['sort'] > $b['sort']; }); 
    foreach($arr as &$val) $val = $val['val']; 
    $ref_arr = $arr; 
    return true; 
} 


Ejemplos:

move_item($arr, 'move me', 'up'); //move it one up 
move_item($arr, 'move me', 'down'); //move it one down 
move_item($arr, 'move me', 'top'); //move it to top 
move_item($arr, 'move me', 'bottom'); //move it to bottom 

move_item($arr, 'move me', -1); //move it one up 
move_item($arr, 'move me', 1); //move it one down 
move_item($arr, 'move me', 2); //move it two down 

move_item($arr, 'move me', 'up', 'b'); //move it before ['b'] 
move_item($arr, 'move me', -1, 'b'); //move it before ['b'] 
move_item($arr, 'move me', 'down', 'b'); //move it after ['b'] 
move_item($arr, 'move me', 1, 'b'); //move it after ['b'] 
move_item($arr, 'move me', 2, 'b'); //move it two positions after ['b'] 

//Special syntax, to swap two elements: 
move_item($arr, 'a', 0, 'd'); //Swap ['a'] with ['d'] 


espero que esto ayuda a mucha gente, porque es una funcion impresionante ¡en! : D

1

Muchos métodos difíciles aquí :) De hecho, puede aprovechar la función de conservar las teclas de array_slice().

$new_element = array('new_key' => 'value'); 

// if needed, find the insertion index by key 
$index = array_search('key to search', array_keys($old_array)); 

// add element at index (note the last array_slice argument) 
$new_array = array_slice($old_array, 0, $index+1, true) + $new_element + array_slice($old_array, $index+1, null, true);