Scot Nery
Scot Nery

Reputation: 699

PHP uasort() not sorting by 3rd dimension of array

I have an array of $cards and each card possibly contains multiple episodes. I want to sort the cards by most recent episode air date.

I have a simple uasort() function.

uasort($cards, function($a, $b) {
 return $a['episodes'][0]['air_date'] <=> $b['episodes'][0]['air_date']; // sort in reverse order by latest episode date
});

Here's the resulting $cards array...

Array
(
    [sam] => Array
        (
            [ID] => 14
            [num] => 626
            [img] => 
            [note] => 
            [search_txt] =>
            [name] => 626
            [status] => 
            [episodes] => Array
                (
                    [0] => Array
                        (
                            [ID] => 1170
                            [series_id] => 3
                            [season_num] => 3
                            [episode_num] => 1
                            [card_id] => 14
                            [air_date] => 2019-09-26
                            [status] => 
                            [shaky] => 0
                        )

                )

        )

    [martha] => Array
        (
            [ID] => 11
            [num] => 628
            [img] => 
            [note] => 
            [search_txt] => 
            [name] => 628
            [status] => 
            [episodes] => Array
                (
                    [0] => Array
                        (
                            [ID] => 1173
                            [series_id] => 3
                            [season_num] => 3
                            [episode_num] => 2
                            [card_id] => 11
                            [air_date] => 2019-10-03
                            [status] => 
                            [shaky] => 0
                        )

                    [1] => Array
                        (
                            [ID] => 1174
                            [series_id] => 4
                            [season_num] => 7
                            [episode_num] => 2
                            [card_id] => 11
                            [air_date] => 2019-10-03
                            [status] => 
                            [shaky] => 0
                        )

                )

        )

    [joey] => Array
        (
            [ID] => 13
            [num] => 627
            [img] => 
            [note] => 
            [search_txt] => 
            [name] => 627
            [status] => 
            [episodes] => Array
                (
                    [0] => Array
                        (
                            [ID] => 1171
                            [series_id] => 4
                            [season_num] => 7
                            [episode_num] => 1
                            [card_id] => 13
                            [air_date] => 2019-09-27
                            [status] => 
                            [shaky] => 0
                        )

                )

        )
)

The array is not sorted correctly. it should be sam, joey, martha. I haven't seen anyone use uasort quite this way, but it seems reasonable to me. Can I go this deep into the array with it? am I just leaving out some important syntax? I'm not getting any errors.

How do I get it to sort by recent episode air_date? Bonus points for sorting by most recent air date.

Upvotes: 0

Views: 94

Answers (2)

AWS PS
AWS PS

Reputation: 4710

Use the code below

function date_compare($a, $b)
{
    usort($a['episodes'], 'date_compare_inner');
    usort($b['episodes'], 'date_compare_inner');
    $t1 = strtotime($a['episodes'][0]['air_date']);
    $t2 = strtotime($b['episodes'][0]['air_date']);
    return $t1 - $t2;
}    

function date_compare_inner($a, $b)
{
    $t1 = strtotime($a['air_date']);
    $t2 = strtotime($b['air_date']);
    return $t1 - $t2;
}  
usort($cards, 'date_compare');

Upvotes: 1

Nigel Ren
Nigel Ren

Reputation: 57131

To sort by the most recent date, then you should extract the list of dates (using array_column() in this code) and then take the max() of the dates...

uasort($cards, function($a, $b) {
    $a1 = max(array_column( $a['episodes'], 'air_date'));
    $b1 = max(array_column( $b['episodes'], 'air_date'));
    return $a1 <=> $b1;
}); 

Upvotes: 1

Related Questions