phparraysstringsortingnatural-sort

Sort array of strings which may containing day and abbreviated month names


I want to sort an array in an ascending direction, but a normal sort approach will not respect the optionally occurring day and month substrings. The strings containing "Feedback" must be sorted by month then day as they appear on the calendar.

Not even natsort() will respect the months as I require.

Example array:

$array = [
    "Feedback 13 okt",
    "Feedback 11 okt",
    "Feedback 12 okt",
    "Sweet",
    "Feedback 9 okt",
    "Feedback 6 okt",
    "Feedback 8 jun",
    "Fixes",
    "Realisation",
    "Feedback 22 mar",
    "Do something",
    "Feedback 3 maj",
    "Feedback 1 dec",
];

Desired result:

[
    'Do something',
    'Feedback 22 mar',
    'Feedback 3 maj',
    'Feedback 8 jun',
    'Feedback 6 okt',
    'Feedback 9 okt',
    'Feedback 11 okt',
    'Feedback 12 okt',
    'Feedback 13 okt',
    'Feedback 1 dec',
    'Fixes',
    'Realisation',
    'Sweet',
]

Solution

  • You should use usort() to implement your own comparison function which first compares two strings without any numbers (use preg_replace('/\d+/', '', $str) for this), and then, if the two strings compared as equal, use strnatcmp() to compare the strings (including numbers) in a natsort() way.

    usort($array, function($a, $b) {
        $cmp = strcmp(preg_replace('/\d+/', '', $a), preg_replace('/\d+/', '', $b));
        if ($cmp) {
            return $cmp;
        } else {
            return strnatcmp($a, $b);
        }
    });