Ver Mensaje Individual
  #1 (permalink)  
Antiguo 05/12/2007, 19:24
Avatar de derkenuke
derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
ordenar con ksort() y dos criterios yuxtapuestos

Bueno, una nueva consulta rebuscadilla:

Supongamos que tengo este array asociativo, cuyas keys son tres valores separados por comas, y cuyos valores son simples integers:
Código PHP:
Array
(
    [
221,79,75] => 3344
    
[162,50,40] => 533
    
[213,63,53] => 30
    
[87,58,24] => 1073
    
[79,45,62] => 1963
    
[143,89,7] => 120
    
[208,100,18] => 29
    
[31,36,86] => 104
    
[165,2,100] => 70
    
[35,70,38] => 82
    
[34,100,15] => 27
    
[145,20,61] => 2
    
[25,56,60] => 3
    
[264,26,38] => 1
    
[327,14,31] => 2
    
[12,27,15] => 1

Si los deseara ordenar por la primera columna de la key, es decir, según los valores 221, 162, 213, 87... puedo usar para ello la función ksort(), pero como me los comparará como string y no como números tengo que hechar mano de uksort() para utilizar un criterio personalizado:
Código PHP:
function criterio($a,$b) {
    
$ha explode(",",$a);
    
$ha = (int) $ha[0];
    
$hb explode(",",$b);
    
$hb = (int) $hb[0];
    return (
$ha<$hb)? -: ( ($ha==$hb)?0:);
}
uksort($miArray"criterio"); 
Y satisfactoriamente da como resultado mi array ordenado por la primera columna del key:
Código PHP:
Array
(
    [
12,27,15] => 1
    
[25,56,60] => 3
    
[31,36,86] => 104
    
[34,100,15] => 27
    
[35,70,38] => 82
    
[79,45,62] => 1963
    
[87,58,24] => 1073
    
[143,89,7] => 120
    
[145,20,61] => 2
    
[162,50,40] => 533
    
[165,2,100] => 70
    
[208,100,18] => 29
    
[213,63,53] => 30
    
[221,79,75] => 3344
    
[264,26,38] => 1
    
[327,14,31] => 2


La duda viene ahora. Supongamos que, teniendo esta ordenación, quiero sub-ordenarla según la segunda columna del key, algo así como una cláusula order by múltiple de SQL. Ahora me diréis que no se puede porque no hay valores iguales en la primera columna, pero yo quiero considerar que son valores iguales todos los que distan entre sí una distancia $d, pongamos que $d=30.

Entonces encontramos en nuestro array varios "grupos" según esa $d:
Código PHP:
// primer grupo, media de la primera columna = 27,4 ~ 27
    
[12,27,15] => 1
    
[25,56,60] => 3
    
[31,36,86] => 104
    
[34,100,15] => 27
    
[35,70,38] => 82
// segundo grupo, media = 83
    
[79,45,62] => 1963
    
[87,58,24] => 1073
// tercer grupo, media = 153,75 ~ 154
    
[143,89,7] => 120
    
[145,20,61] => 2
    
[162,50,40] => 533
    
[165,2,100] => 70
// cuarto grupo, media = 214
    
[208,100,18] => 29
    
[213,63,53] => 30
    
[221,79,75] => 3344
// quinto grupo, media = 264
    
[264,26,38] => 1
// sexto grupo, media = 327 
    
[327,14,31] => 
Todavía estoy sin decidir cómo agrupar esos números, con qué algoritmo. Bueno, definidos esos grupos tendríamos este array ficticio a ordenar:
Código PHP:
Array
(
    [
27,27,15] => 1
    
[27,56,60] => 3
    
[27,36,86] => 104
    
[27,100,15] => 27
    
[27,70,38] => 82

    
[83,45,62] => 1963
    
[83,58,24] => 1073

    
[154,89,7] => 120
    
[154,20,61] => 2
    
[154,50,40] => 533
    
[154,2,100] => 70

    
[214,100,18] => 29
    
[214,63,53] => 30
    
[214,79,75] => 3344

    
[264,26,38] => 1

    
[327,14,31] => 2

Que consiguiríamos ordenarlo según la segunda columna con éste resultado:
Código PHP:
Array
(
    [
27,27,15] => 1
    
[27,36,86] => 104
    
[27,56,60] => 3
    
[27,70,38] => 82
    
[27,100,15] => 27

    
[83,45,62] => 1963
    
[83,58,24] => 1073

    
[154,2,100] => 70
    
[154,20,61] => 2
    
[154,50,40] => 533
    
[154,89,7] => 120

    
[214,63,53] => 30
    
[214,79,75] => 3344
    
[214,100,18] => 29

    
[264,26,38] => 1

    
[327,14,31] => 2


Bueno, incluso podríamos hacer lo mismo recursivamente para la tercera columna etc, pero los grupos son tan reducidos en elementos que ya ni me interesa. A todo este proceso supongo que no debo decir que no puedo perder las keys del array original (en estos ultimos ejemplos las he machacado)



La cuestión en sí: Ordenar el array según un criterio que lo ordene de menor a mayor en la primera columna, y después agrupar ciertos valores del array según una variable $d (definir el algoritmo) para reordenar los sub-grupos restantes según la segunda columna de menor a mayor también.



Espero que se me entienda, estoy totalmente perdido y no he podido ni intentar nada al respecto



__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.