-1

I have an array of people's names:

Array
(
    [1] => A. Aitken
    [2] => A. C. Skinner
    [3] => A. Chen
    [4] => R. Baxter
)

What's the quickest way to sort the array in (alphabetical) order of the surname in php? i.e. to give

Array
(
    [1] => A. Aitken
    [4] => R. Baxter
    [3] => A. Chen
    [2] => A. C. Skinner
)

4 Answers 4

5
function cmp($a, $b)
{
    $a1 = explode(' ', $a);
    $b1 = explode(' ', $b);
    return strcasecmp(end($a1), end($b1));
}

usort($arr, 'cmp');
Sign up to request clarification or add additional context in comments.

Comments

3

Have a look at uksort and the example given there, which is very similar to your problem.

You may want to replace the regexps there with

preg_replace("/[A-Z]\\. /", '', $a);

1 Comment

Thanks - this works. For completeness you might just want to correct the typo in the pattern - I think it should be "@[A-Z]\\. @" (or "/[A-Z]\\. /").
1

You can sort using decorate-sort-undecorate pattern by key being last element of array that is result of splitting your string with spaces

$arr = array(                                                                                                                                               
'A. Aitken',                                                                                                                                               
'A. C. Skinner',                                                                                                                                           
'A. Chen',                                                                                                                                                 
'R. Baxter'                                                                                                                                                
);                                                                                                                                                          

// actual sorting below                                                                                                                                     
$arr= array_map(create_function('$a', 'return array(array_slice(explode(" ", $a), -1), $a);'), $arr); // transform into array of arrays consisted of sort key and item  
sort($arr); // sort array of arrays                                                                                                                         
$arr = array_map('end', $arr); // take only last element from each array                                                                                    

print_r($arr);                                                                                                                                              

2 Comments

That gives a lot of E_STRICT warnings.
@Daniel Egeberg - thanks, I've fixed this by replacing end() with array_slice(,-1);
0

Because it is not performant to call two or more functions on each iteration of uasort() AND because array_multisort() will not preserve numeric keys, I have devised a script to minimize iterated function calls and separately preserve keys while using array_multisort().

Code: (Demo)

$firsts = [];
$lasts = [];
$keys = [];
foreach ($array as $keys[] => $v) {
    [$firsts[], $lasts[]] = preg_split('/.*\K |^/', $v);
}
array_multisort($lasts, $firsts, $keys, $array);
var_export(array_combine($keys, $array));

The above script populates separate (equally sized) arrays for first names, last names and original keys.

The regular expression splits on the last occurring space OR if that doesn't exist, it splits on the position before the first character (meaning the first name value will be blank).

array_multisort() will sort by last names ASC, then first names ASC, then keys ASC (but by this point there will be no ties to break), then the full name values ASC (but again, there will be no ties to break).

array_combine() is called to re-associate the keys with their original values in their new positions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.