yenren
yenren

Reputation: 501

Sort PHP multidimensional array based on child array value, then main array key

I have a PHP array like the following:

$array = array(
    '06930' => array(
        'count' => 20
    ),
    '06905' => array(
        'count' => 25
    ),
    '06910' => array(
        'count' => 15
    ),
    '06903' => array(
        'count' => 15
    ),
    '06920' => array(
        'count' => 10
    ),
    '06940' => array(
        'count' => 5
    ),
    '06915' => array(
        'count' => 10
    ),
);

Contains zip codes and some data (count, ...) related to that zip. I need to sort it based on count (DESC), and then sort it again based on zip code (ASC), so that the result will be as follows:

$array = array(
    '06905' => array(
        'count' => 25
    ),
    '06930' => array(
        'count' => 20
    ),
    '06903' => array(
        'count' => 15
    ),
    '06910' => array(
        'count' => 15
    ),
    '06915' => array(
        'count' => 10
    ),
    '06920' => array(
        'count' => 10
    ),
    '06940' => array(
        'count' => 5
    ),
);

Zip with bigger count will be above others, but if two zips have equal count, smaller zip will be above.

I can sort it based on count using:

uasort($array, function ($a, $b) {
    return $b['count'] <=> $a['count'];
});

But can't sort based on zip afterwards.

I reviewed many similar questions and answers but still couldn't figure out how to sort second time by the main array key (zip).

Thanks for any tips.

Upvotes: 1

Views: 397

Answers (3)

jspit
jspit

Reputation: 7703

The short version of @Nigel Ren's answer:

uksort($array, function ($a, $b) use ($array) {
    return $array[$b]['count'] <=> $array[$a]['count'] ?: $a <=> $b;
});

Upvotes: 1

Nigel Ren
Nigel Ren

Reputation: 57121

You can change it to use uksort() which gives you the keys to sort with, you will need to pass the array in as well (using use) so that it can access the values as well.

This checks if the counts are the same, if they are it will compare the keys instead...

uksort($array, function ($a, $b) use ($array) {
    if ( $array[$b]['count'] ==  $array[$a]['count'])   {
        return $a <=> $b;
    }
    return $array[$b]['count'] <=> $array[$a]['count'];
});

Upvotes: 1

Death-is-the-real-truth
Death-is-the-real-truth

Reputation: 72299

use array_multisort()

array_multisort(array_column($array,'count'), SORT_DESC, SORT_NUMERIC,
                array_keys($array), SORT_NUMERIC, SORT_ASC,$array);

Output: -https://3v4l.org/QCrZf

Upvotes: 1

Related Questions