¿Cómo reordenar array con array_multisort() reinterpretando ciertos valores?

adruiz Seguir

Beta
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
12 Abr 2021
Mensajes
145
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 👍
 

merkonmerkon

Gamma
Verificación en dos pasos desactivada
Verificado por Whatsapp
Desde
28 Sep 2010
Mensajes
375
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.
 

adruiz

Beta
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
12 Abr 2021
Mensajes
145
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 👍
 

mchojrin

Beta
Verificación en dos pasos desactivada
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
10 Feb 2017
Mensajes
103
¿Tal vez usando usort junto con una función anónima?
 

adruiz

Beta
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
12 Abr 2021
Mensajes
145
¿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 edición:

mchojrin

Beta
Verificación en dos pasos desactivada
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
10 Feb 2017
Mensajes
103
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 ;)
 

¡Regístrate y comienza a ganar!

Beneficios

  • Gana dinero por participar
  • Gana dinero por recomendarnos
  • Descubre ofertas de empleo diariamente
  • Negocios seguros
  • ¡Información premium y más!

Acceder

¿Ya tienes una cuenta? Accede aquí

Arriba