Ordene una matriz asociativa multidimensional por una columna y conserve las claves de primer nivel

4 minutos de lectura

avatar de usuario de acrmuui
acrmuui

Tengo una matriz que se ve así:

$this->wordswithdata = [
    'team1' => [
        'points' => 10,
        'players' => [],
    ],
    'team2' => [
        'points' => 23,
        'players' => []
    ]
];

y me gustaría ordenar los equipos por el número de puntos que cada equipo tiene de mayor a menor. He intentado esto:

function sort_by_points($a,$b)
{
    if ($a['points'] == $b['points']) return 0;
        return ($a['points'] < $b['points']) ? 1 : -1;
}

usort($this->wordswithdata, "sortbycount");

Pero ese enfoque anula las claves que contienen los nombres de equipo y devuelve:

[
    0 => [
        'points' => 23,
        'players' => []
    ],
    1 => [
        'points' => 10,
        'players' => [],
    ]
]

¿Hay alguna forma de ordenar la matriz sin perder los nombres de los equipos como claves de la matriz?

avatar de usuario de complex857
complejo857

Utilizar el sortear función, que debería mantener intactas las asociaciones clave => valor.

(nota al margen: usted puede hacer return $a['points'] - $b['points'] en lugar de los ifs, o a partir de php7 el espaciohsip <=> operadorgracias mbomb007 por la actualización)

  • A partir de PHP 7, puedes usar el operador de la nave espacial <=> en lugar de restar. Ver la respuesta de esta pregunta relacionada

    – bombomb007

    13 de marzo a las 18:52

Avatar de usuario de Shoe
Zapato

Puedes usar uasort:

uasort($array, function($a, $b) {
    return $a['points'] - $b['points'];
});

Esta función ordena una matriz tal que los índices de la matriz mantener su correlación con los elementos de matriz con los que están asociados, utilizando una función de comparación definida por el usuario.

U puede ordenar una matriz asociativa por su valor como este

$age = array("Peter"=>"35", "Ben"=>"37", "Joe"=>"43");

function Ascending($a, $b) {   
    if ($a == $b) {        
        return 0;
    }   
        return ($a < $b) ? -1 : 1; 
}  

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


echo "Ascending order" ;
uasort($age,"Ascending");
print_r($age);


echo "</br>Descending order" ;
uasort($age,"Descending");
print_r($age);

Prueba este código, espero que funcione.

function aasort (&$array, $key) {
    $sorter=array();
    $ret=array();
    reset($array);
    foreach ($array as $ii => $va) {
        $sorter[$ii]=$va[$key];
    }
    asort($sorter);
    foreach ($sorter as $ii => $va) {
        $ret[$ii]=$array[$ii];
    }
    $array=$ret;
}

aasort($your_array,"points");

its working fine i giving example
that array need sort
$sumarray=array [▼
  484 => 54.7875
  486 => 53.5375
  487 => 52.9125
  488 => 52.2875
  493 => 54.7875
]

$original=$sumarray;

 $svalue=array_values($sumarray);
  rsort($svalue);
  $sorted=array();
  foreach ($svalue as $key => $value) {
   $kk=array_search($value,$sumarray);
  $sorted[$kk]=$value;
  unset($sumarray[$kk]);

    }
  print_r($original);
    print_r($svalue);
  print_r($sorted);
             //out put
  array:5 [▼
  484 => 54.7875
  486 => 53.5375
  487 => 52.9125
  488 => 52.2875
  493 => 54.7875
]
array:5 [▼
  0 => 54.7875
  1 => 54.7875
  2 => 53.5375
  3 => 52.9125
  4 => 52.2875
]
array:5 [▼
  484 => 54.7875
  493 => 54.7875
  486 => 53.5375
  487 => 52.9125
  488 => 52.2875
]

  • Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. A explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.

    – Capricornio

    30 de julio de 2018 a las 8:54

  • No puedo imaginar ningún escenario posible en el que me gustaría invitar a este tipo de código indirecto/intrincado a mi proyecto. Aparte del hecho de que esta respuesta ignoró la misma estructura de datos, ¿por qué alguien con una matriz asociativa plana debería llamar array_values()entonces rsort()luego haga llamadas iteradas de array_search() y unset()???

    – mickmackusa

    15 de marzo a las 21:04

avatar de usuario de mickmackusa
mickmackusa

Para completar, esta página debe incluir un enfoque usando array_multisort() — esta función conservará las claves no numéricas de forma predeterminada.

Código: (Manifestación)

array_multisort(
    array_column($array, 'points'),
    SORT_DESC,
    $array
);

Dicho esto, no hay nada de malo en llamar uasort() con el operador de la nave espacial. Tenga en cuenta que $b los datos están en el lado izquierdo del operador de comparación de tres vías y $a está en el lado derecho para lograr una ordenación descendente.

Código: Manifestación

uasort(
    $array,
    fn($a, $b) => $b['points'] <=> $a['points']
);

  • Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. A explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.

    – Capricornio

    30 de julio de 2018 a las 8:54

  • No puedo imaginar ningún escenario posible en el que me gustaría invitar a este tipo de código indirecto/intrincado a mi proyecto. Aparte del hecho de que esta respuesta ignoró la misma estructura de datos, ¿por qué alguien con una matriz asociativa plana debería llamar array_values()entonces rsort()luego haga llamadas iteradas de array_search() y unset()???

    – mickmackusa

    15 de marzo a las 21:04

¿Ha sido útil esta solución?