Como reordenar array com array_multisort() reinterpretando certos valores?

  • Autor Autor adruiz
  • Data de início Data de início
Tradução em andamento: em alguns minutos este tópico estará em português. Por enquanto, o conteúdo está no original em espanhol. Ver original
adruiz

adruiz

Gamma
Verificación en dos pasos activada
Tengo una duda, a ver si alguien puede echarme un cable.

Tengo un array en el que cada elemento tiene un apartado numérico, llamémoslo "number", y en algunos ese número es sobre un máximo de 10 y en otros de 100. Por ejemplo:
PHP:
$array = [
    "A" => [
        "name" => "Volvo",
        "number" => "9"
    ],
    "B" => [
        "name" = "Audi",
        "number" = "96"
    ],
    "C" => [
        "name" = "BMW",
        "number" = "9.7"
    ]
]

Dicho array lo reordeno mediante array_multisort() de la siguiente manera:
PHP:
array_multisort(array_column($array, 'number'), SORT_DESC, SORT_NUMERIC, $array);

Pero 96 es más grande que 9.7 y 9, lo cual es lógico. Lo que me interesa es reinterpretar los valores que son sobre 100 (cualquiera superior a 10), que ese 96 se interprete como un 9.6, pero ojo, no reformateando el número, necesito que el valor original del array siga siendo 96, ya que luego lo necesito para otras cosas.

Para entenderlo mejor, lo que necesito es reordenar el array de modo que: 9.7 > 96 > 9.

¿Alguna sugerencia? Gracias 👍
 
Foi útil? Participe da conversa

Com sua conta grátis você pode responder, mandar mensagem privada ao autor e comprar com Saldo retido: o pagamento é liberado quando você recebe o combinado.

Leva 30 segundos · você volta a este tópico ao terminar
Vas a tener que reformatearlo, ordenarlo con array_multisort y después volver a re-reformatearlo para dejarlo como lo tenías antes.
Podés guardar en otro elemento el valor orignal para poder 're-reformatearlo' correctamente en el último paso.
 
Vas a tener que reformatearlo, ordenarlo con array_multisort y después volver a re-reformatearlo para dejarlo como lo tenías antes.
Podés guardar en otro elemento el valor orignal para poder 're-reformatearlo' correctamente en el último paso.
Es lo que me temía. Va a ser difícil, ya que es un array multidimensional bastante complejo.

¡Gracias por tu respuesta! Veré cómo lo soluciono 👍
 
¿Tal vez usando usort junto con una función anónima?
 
¿Tal vez usando usort junto con una función anónima?
Es justo lo que buscaba! Gracias por el consejo, conocía usort pero no su uso correcto, me lo estudié un poco y tras tastear con el código he dado con la tecla. En realidad más que usort he usado uasort, para conservar la asociación de los índices.

Por si le fuera a servir a alguien algún día, dejo por aquí el código, tomando de referencia el ejemplo que puse arriba:
PHP:
function cmp(array $a, array $b) {
    $a = decimalToUnit($a['number']);
    $b = decimalToUnit($b['number']);

    if ($a == $b) {
        return 0;
    }
    return ($a > $b) ? -1 : 1;
}

uasort($array, 'cmp');

Señalar que la función decimalToUnit() es una función aparte que he creado, básicamente para reconvertir decimales en unidades y que así cmp interprete todas las cifras sobre la misma escala.

Gracias por la observación, @mchojrin 👍
 
Última edição:
Excelente! Le cambiaría un detallín si me lo permites 🙂

PHP:
uasort($array, function(array $a, array $b) {
    $a = decimalToUnit($a['number']);
    $b = decimalToUnit($b['number']);

    if ($a == $b) {
        return 0;
    }
    return ($a > $b) ? -1 : 1;
});

Como para hacerlo más compacto nomás 😉
 
Voltar
Topo