Simon Blackbourn
Simon Blackbourn

Reputation: 278

How to sort an array of names by surname preserving the keys

I have an array as follows:

Array(
    [27] => 'Sarah Green',
    [29] => 'Adam Brown',
    [68] => 'Fred Able'
);

I'd like to sort it by surname and preserve the keys:

Array(
    [68] => 'Fred Able'
    [29] => 'Adam Brown',
    [27] => 'Sarah Green'
);

Some names may have more than two first names, but it's always the very last name I want to sort on.

What would be the best way to do this in PHP?

Upvotes: 6

Views: 6093

Answers (7)

Vikrant Kekan
Vikrant Kekan

Reputation: 22

<?php
$names= Array('Fred Able','Adam Brown','Sarah Green');

$new_arr=array();

$clength = count($names);
for($x = 0; $x < $clength; $x++) {

  $y= array_reverse(explode(' ',$names[$x]));
  
  $y=implode(" ",$y);
  
  array_push($new_arr,$y);
  
}

rsort($new_arr); // for rsort sorting with descending order,  for ASC use sort

print_r($new_arr);

?>

Upvotes: 0

Mauro
Mauro

Reputation: 4224

You will probably want to create an auxiliar array with the surnames, keep the key, order it and then reconstruct the original array:

function order_by_surname($names) {
    foreach ($names as $key => $name) {
        $surnames[$key] = array_pop(explode(' ', $name));
    }
    asort($surnames);
    foreach ($surnames as $key => $surname) {
        $ordered[$key] = $names[$key];
    }
    return $ordered;

}

Also, note that you may have problems with this because the surname is not always the last word of a full name when you have two surnames (e.g. John Clark Moore).

Upvotes: 0

Matthew Scragg
Matthew Scragg

Reputation: 4638

function sortByLastName($a){
    $tmp = $a;
    foreach($tmp as $k => $v){
        $tmp[$k] = substr($v,strrpos($v, ' ')+1);
    }
    asort($tmp);
    $ret = array();
    foreach($tmp as $k => $v){
        $ret[$k] = $a[$k];
    }
    return $ret;
}

Maybe not the fastest way but it works. It works if they have middle names too.

This is faster than the accepted answer.

http://codepad.org/ogGibRpH

Upvotes: 1

user399666
user399666

Reputation: 19879

I'm not sure if there's a straight-forward way of sorting your example array by surnames.

You could add names to the array in a different manner. i.e. "Fred Able" would become "Able, Fred". That would allow you to use PHP's inbuilt array-sorting functions.

Failing that, you might have to go through each array element and explode by whitespace, using the last piece of the returned array as your surname. A bit messy, but I'm sure there are tonnes of examples and functions out there.

Upvotes: 0

anson
anson

Reputation: 4164

Probably something similar to this (have not tested)

function sortSurname($a,$b){
  $sur_a = array_pop(explode(' ',$a));
  $sur_b = array_pop(explode(' ',$b));
  return $sur_a < $sur_b;
}

usort($array, 'sortSurname')

Upvotes: 0

Ry-
Ry-

Reputation: 224942

You can use the uasort function, which allows you to specify a custom sorting method while also preserving keys:

<?php
// A function to sort by last name.
function lastNameSort($a, $b) {
    $aLast = end(explode(' ', $a));
    $bLast = end(explode(' ', $b));

    return strcasecmp($aLast, $bLast);
}

// The array of data.
$array = array(
    27 => 'Sarah Green',
    29 => 'Adam Brown',
    68 => 'Fred Able'
);

// Perform the sort:
uasort($array, 'lastNameSort');

// Print the result:
print_r($array);
?>

Here's a demo.

Upvotes: 11

christophmccann
christophmccann

Reputation: 4211

I don't think you could directly do this with PHP's built-in array sorting - although I would be interested if someone corrected me on this.

The easiest way would be to reverse the names so that it becomes Green, Sarah because then you could use PHPs own sorting functions e.g. using asort() (which maintains the key association).

If that isn't feasible you will probably need to implement your own custom sorting function. The easiest way of doing that, is to use usort() which allows you to define a custom comparator function. So for example:

usort($arr, "sortByLastName");

function sortByLastName($a, $b) {
     //DO YOUR COMPARISON IN HERE
}

Upvotes: 0

Related Questions