按名称列对2d数组进行排序,但忽略名称';前缀


Sort a 2d array by its name column but ignoring the names' prefixes

我想按name列值对行数组进行排序,但关键是我想在忽略用户前缀的情况下进行排序。

样品阵列:

$ad_users = [
    ["name" => "Mr San", "department" => "five"],
    ["name" => "Mr VSan", "department" => "six"],
    ["name" => "Mr QSan", "department" => "four"],
    ["name" => "Sr ASan", "department" => "two"],
    ["name" => "Dr ASan", "department" => "one"],
    ["name" => "Dr FSan", "department" => "three"]
];

期望结果:

[
    ["name" => "Dr ASan", "department" => "one"],
    ["name" => "Sr ASan", "department" => "two"],
    ["name" => "Dr FSan", "department" => "three"],
    ["name" => "Mr QSan", "department" => "four"],
    ["name" => "Mr San", "department" => "five"],
    ["name" => "Mr VSan", "department" => "six"]
]

我当前的代码:

for ($x = 0; $x < count($ad_users); $x++) {
    $ad_users[$x]['name']= ucwords($ad_users[$x]['name']);
    $end = (explode(',', $ad_users[$x]['name']));
    $lastname = array_pop($end);
    sort($end);
    $firstname = implode(" ", $end);
    $ad_users[$x]['name']=$lastname." ".$firstname;
}
sort($ad_users);
for ($x = 0; $x < count($ad_users); $x++) {
    echo $ad_users[$x]['name']."'n";
}
    <?php
        uasort($array, function($a, $b) {
            $needles = ['Dr.', 'Ms.', ];
            $a = trim(str_replace($needles,'', $a['name']));
            $b = trim(str_replace($needles,'', $b['name']));
            if ($a == $b) {
                return 0;
            }
            return ($a < $b) ? -1 : 1;
        });

您在评论中明确表示,您最初的名称为firstname lastname, title,因此您只需要先排序,然后将标题移到前面:

<?php
sort($ad_users);
// I've copied this section as-is, it looks like it could be improved
// but I can't be sure I'm making the correct improvements without seeing
// the original data
for ($x = 0; $x < count($ad_users); $x++) {
    $ad_users[$x]['name']= ucwords($ad_users[$x]['name']);
    $end = (explode(',', $ad_users[$x]['name']));
    $lastname = array_pop($end);
    sort($end);
    $firstname = implode(" ", $end);
    $ad_users[$x]['name']=$lastname." ".$firstname;
}
for ($x = 0; $x < count($ad_users); $x++) {
    echo $ad_users[$x]['name']."'n";
}
?>

您应该准备数据(删除所有Dr.、Ms等),然后只对已清理的名称进行排序。

首先:不要对for循环中的常量数组进行计数()!您使用不存在的分隔符explode(),因此生成的数组只有一个元素,您可以使用array_pop()删除该元素。然后对()进行排序并内爆()一个空数组。所以你会得到一个随机的(在这种情况下是不变的)结果。

请检查http://php.net/usort

您可以将代码更改为

<?php
function sortByOrder($a, $b) {
     $prefix = ['Mr.', 'Ms.','Dr.'];
     $a = trim(str_replace($prefix,"", $a['name']));
     $b = trim(str_replace($prefix,"", $b['name']));
    return $a > $b;
}
$myArray = array(
      array("name"=>"Dr.    bbb"),
      array("name"=>"Mr. aaa"),
      array("name"=>"Ms.  ccc")
);
$abc = usort($myArray, 'sortByOrder');
print_r($myArray);
?>

查看此处:https://eval.in/569467

输出为:

Array
(
    [0] => Array
        (
            [name] => Mr. aaa
        )
    [1] => Array
        (
            [name] => Dr.    bbb
        )
    [2] => Array
        (
            [name] => Ms.  ccc
        )
)

usort()具有更昂贵的时间复杂性,并且在每次迭代中需要加倍的函数调用。相反,我建议使用array_multisort(),并准备一个具有最少函数调用的排序数组。

隔离name列的值,然后修剪每个值的前缀,然后比较这些字符串。之后,您可以通过对整行进行排序来有效地对前缀进行排序。

代码:(演示)

array_multisort(
    preg_replace('/^[^ ]+ /', '', array_column($data, 'name')),
    $data
);