如何按姓氏对姓名数组进行排序并保留键值

6

我有一个以下形式的数组:

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

我希望按照姓氏对其进行排序并保留键:

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

一些姓名可能有两个以上的名字,但我始终想按照最后一个名字进行排序。

在PHP中,最好的方法是什么?

7个回答

11

你可以使用uasort 函数来指定自定义排序方法并保留键值:

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

这里有一个演示。


1
非常出色和迅速的回应。但是,与实际结果无关,end将其参数作为引用。这将导致“严格标准”错误。要修复此问题,只需先将explode(' ', $a)explode(' ', $b)分配给变量即可。抱歉,我只是挑剔了一下。 - bob-the-destroyer
@bob-the-destroyer:啊,好的。谢谢你指出来!挑剔是好事 :) - Ry-
非常好用,比我之前想了很久却没有进展的想法更加优雅!感谢 @bob-the-destroyer 的贴士。 - Simon Blackbourn
1
@bob-the-destroyer:是的,那只是一个示例函数。 - Ry-
@minitech:收到。我会把剩下的交给OP处理。 - bob-the-destroyer

1
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;
}

也许不是最快的方法,但它有效。即使他们有中间名字,它仍然有效。

这比被接受的答案更快。

http://codepad.org/ogGibRpH


0

我认为你不能直接使用PHP内置的数组排序来做到这一点,不过如果有人纠正我,我会很感兴趣。

最简单的方法是反转名称,使其变成Green,Sarah,因为这样你就可以使用PHP自己的排序函数,例如使用asort()(它维护键关联)。

如果这不可行,你可能需要实现自己的自定义排序函数。最简单的方法是使用usort(),它允许你定义一个自定义比较器函数。例如:

usort($arr, "sortByLastName");

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

0

可能类似于这个(尚未测试)

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

usort($array, 'sortSurname')

0

你可能想要创建一个辅助数组来存储姓氏,保留键值,对其进行排序,然后重构原始数组:

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;

}

此外,请注意,如果您有两个姓氏(例如John Clark Moore),则姓氏不总是全名的最后一个单词,因此可能会遇到问题。

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

?>

1
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - Suraj Rao

0

我不确定是否有一种直接的方法可以按姓氏对你的示例数组进行排序。

您可以以不同的方式向数组中添加名称。例如,“Fred Able”将变为“Able,Fred”。这将允许您使用PHP的内置数组排序函数。

如果失败,您可能需要逐个遍历每个数组元素并按空格分隔,使用返回的数组的最后一部分作为您的姓氏。有点混乱,但我相信那里有大量的示例和函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接