Custom sort strings -- if starting with a specific string, then alphabetically

Viewed 1491

I would like to sort strings in PHP, and the match should be done foremost on the first letters of a substring, then on the letters of the whole the string.

For example, if someone searches do, and the list contains

Adolf
Doe
Done

the result should be

Doe
Done
Adolf

Using the regular sort($array, SORT_STRING) or things like that does not work, Adolf is sorted before the others.

Does someone have an idea how to do that?

4 Answers

In modern PHP, writing two rules can be done more concisely than in the past.

Order by:

  1. Starts with do -- false evaluations come before true evaluations
  2. Break ties on the first rule by case-insensitively comparing the whole strings

Code: (Demo)

$array = [
    'Adolf',
    'Doe',
    'adept',
    'Done',
    'dear',
    'adopt',
    'Deer'
];

$startsWith = 'do';

usort(
    $array,
    fn($a, $b) =>
        (stripos($a, $startsWith) !== 0) <=> (stripos($b, $startsWith) !== 0)
        ?: strcasecmp($a, $b)
);
var_export($array);

More efficiently (because fewer iterated function call are made) than above, I recommend array_multisort(). The final parameter ($array) is the variable that is ultimately modified by the function.

Code: (Demo)

array_multisort(
    array_map(fn($v) => stripos($v, $startsWith) !== 0, $array),
    $array,
    SORT_STRING | SORT_FLAG_CASE,
    $array
);
Related