'Sort a multidimensional array by integer inside of a string value which is two levels down

I have a multidimensional array in php:

Array (
    [0] => Array ( 
        [certificate_name] => track.site 
        [domains] => track.site
        [expiry_date] => Array ( 
            [date] => 2018-09-25 
            [time] => 10:11:58 
            [count] => (22)
        )
    )
    [1] => Array (
        [certificate_name] => stats.com
        [domains] => stats.com
        [expiry_date] => Array (
            [date] => 2018-09-24
            [time] => 10:11:58
            [count] => (43)
        )
    )
)

I want to sort this multidimensional array by $array['expiry_date']['count']



Solution 1:[1]

This can be done with usort:

$data = [
    [
        'certificate_name' => 'track.site',
        'domains' => 'track.site',
        'expiry_date' => [
            'date' => '2018-09-25',
            'time' => '10:11:58',
            'count' => 22,
        ]
    ],
    [
        'certificate_name' => 'stats.com',
        'domains' => 'stats.com',
        'expiry_date' => [
            'date' => '2018-09-24',
            'time' => '10:11:58',
            'count' => 43,
        ]
    ]
];

function compare_by_expiry_date_count($a, $b) {
    return $a["expiry_date"]['count'] > $b["expiry_date"]['count'];
}


usort($data, "compare_by_expiry_date_count");

var_dump($data);

Solution 2:[2]

If I don't misunderstood your question then you need sorting by count not filtering. Also use trim() to remove parenthesis from the count value. Hope it helps :)

Try like this way, $b-$a is for desc, $a-$b is for asc

<?php
// this $b-$a is for desc, for asc try $a-$b
function sorting_by_count($a, $b)
{
    return trim($b['expiry_date']['count'],'()') - trim($a['expiry_date']['count'],'()');
}
$array = [
    [
        'certificate_name' => 'track.site',
        'domains' => 'track.site',
        'expiry_date' => [
            'date' => '2018-09-25',
            'time' => '10:11:58',
            'count' => '(22)',
        ]
    ],
    [
        'certificate_name' => 'stats.com',
        'domains' => 'stats.com',
        'expiry_date' => [
            'date' => '2018-09-24',
            'time' => '10:11:58',
            'count' => '(43)',
        ]
    ]
];
usort($array, 'sorting_by_count');
print_r($array);
?>

DEMO: https://3v4l.org/vtRIu

Solution 3:[3]

For best time complexity, loop through your rows and populate a flat array containing the count values after trimming the parentheses and casting to an integer.

Then call array_multisort() with the counts array as the first argument and the original array as the second argument.

Code: (Demo)

foreach ($array as $row) {
    $counts[] = (int) trim($row['expiry_date']['count'], '()');
}
array_multisort($counts, $array);
var_export($array);

Using usort() and calling trim() on every iteration will be more expensive because it will have to re-trim values that were already encountered.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Barry
Solution 2 Always Sunny
Solution 3 mickmackusa