2012-06-19 13 views
7

tengo la siguiente matriz:Ordenar un array usando array_multisort

$array = array(
     'note' => array(), 
     'year' => array('2011','2010', '2012'), 
     'type' => array('conference', 'journal', 'conference'), 
    ); 

Y utilizo la siguiente función para ordenar la matriz utilizando el tipo de campo y otra matriz:

function array_multisort_by_order(array $array, $by, array $order) 
{ 
    $order = array_flip($order); 
    $params[] = $array[$by]; 
    foreach($params[0] as &$v) $v = $order[$v]; 
    foreach($array as &$v) $params[] = &$v; unset($v); 
    call_user_func_array('array_multisort', $params); 
    return $array; 
} 

Cuando llamo a la siguiente función me sale el siguiente error:

$array = array_multisort_by_order($array, 'type', array('conference', 'journal')); 

print_r($array['type']); 

error:

Warning: array_multisort(): Array sizes are inconsistent. 

Sé que las matrices son inconsistentes. ¿Hay una mejor función para usar?

Por favor marque: codepad

salida deseada:

Array 
(
[note] => Array 
    (
     [0] => 
     [1] => 
     [2] => 
    ) 

[year] => Array 
    (
     [0] => 2011 
     [1] => 2012 
     [2] => 2010 
    ) 

[type] => Array 
    (
     [0] => conference 
     [1] => conference 
     [2] => journal 
    ) 

) 

Ejemplo 2:

matriz

$array = array(
     'note' => array([0]=>'test1', [1]=>'test2'), 
     'year' => array([0]=>'2011', [2]=>'2012'), 
     'type' => array([0]=>'conference',[1]=>'journal', [2]=>'conference'), 
    ); 

Resultado Deseado 2

Array 
(
[note] => Array 
    (
     [0] => test1 
     [1] => 
     [2] => tes2 
    ) 

[year] => Array 
    (
     [0] => 2011 
     [1] => 2012 
     [2] => 
    ) 

[type] => Array 
    (
     [0] => conference 
     [1] => conference 
     [2] => journal 
    ) 

) 

Gracias

+3

Hm, salida deseada haría las cosas más claro que cuestionarlo desde el código. ¿Podrías proporcionar eso? – Wrikken

+0

añadido resultado deseado! – glarkou

+0

OK, queda 1 pregunta: los subparámetros siempre están vacíos o tienen una longitud constante, o podemos esperar un subarreglo con 2 elementos aquí, y si es así, ¿cómo lidiamos con eso? ¿Suponen que aún coinciden con los primeros 2 elementos de los otros submajos? – Wrikken

Respuesta

3

OK, entonces, una de las primeras soluciones que viene a la mente es la adición de los valores vacíos para que sean consistentes:

function array_multisort_by_order(array $array, $by, array $order) 
{ 
    $max = max(array_map('count',$array)); 
    //or, alternatively, depending on input (if there are no 'complete' subarrays): 
    //$max = max(array_map(function($arr){return max(array_keys($arr));},$array))+1; 

    //ADDITION: negative numeric keys: 
    $min = min(array_map(function($arr){return min(array_keys($arr));},$array)); 
    $width = $max - min(0,$min); 

    foreach($array as &$sub){ 
     // $addin = array_diff_key(array_fill(0,$max,null),$sub); 
     // $addin changed for negative keys: 
     $addin = array_diff_key(array_combine(range($min,$max),array_fill(0,$width,null)),$sub); 
     $sub = $addin + $sub; 
     ksort($sub); 
    } 
    $order = array_flip($order); 
    $params[] = $array[$by]; 
    foreach($params[0] as &$v) $v = $order[$v]; 
    foreach($array as &$v) $params[] = &$v; unset($v); 
    call_user_func_array('array_multisort', $params); 
    //no closeures here: 
    //foreach($array as &$sub) $sub = array_filter(function($a){return !is_null($a);},$sub); 
    $filter = create_function('$a','return !is_null($a);'); 
    foreach($array as &$sub) $sub = array_filter($sub,$filter); 
    return $array; 
} 
+0

Sí, yo pensé en eso. Y lo hice http://codepad.org/4QcAoemv pero en realidad no está agregando las claves a la matriz original. Además, ¿hay alguna manera de deshacerse de esos valores 'vacíos' después de hacer el multisort? – glarkou

+0

Ugh, el teclado se está ejecutando <5.3, no puede usar cierres ... Algo como esto te refieres a: http://codepad.org/5kMHlRc6 – Wrikken

+0

Sí, eso hará el trabajo. Si puede verificar el código, intenté usar un método más simple para completar las teclas faltantes 'foreach ($ array ['type'] como $ k => $ v) { foreach ($ array as $ element => $ a) { $ iterator = $ array [$ elemento]; if (! Isset ($ iterator [$ k])) { $ iterator [$ key] = ''; } } } '. Esto fue temporal llenando la matriz '$ iterator' y no la matriz original. Gracias de nuevo por su ayuda, usaré su solución. Lo marqué como correcto. ¿Puedes por favor editar tu respuesta? – glarkou

Cuestiones relacionadas