Tomba
Tomba

Reputation: 1753

sorting array of names in php

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
)

Upvotes: -1

Views: 1327

Answers (4)

mickmackusa
mickmackusa

Reputation: 48071

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.

Upvotes: 0

Kamil Szot
Kamil Szot

Reputation: 17817

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);                                                                                                                                              

Upvotes: 1

mvds
mvds

Reputation: 47114

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);

Upvotes: 3

Daniel Egeberg
Daniel Egeberg

Reputation: 8382

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

usort($arr, 'cmp');

Upvotes: 5

Related Questions