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

973

I want to sort an array of rows by thename column value, but critically I want to sort while ignoring the users' prefixes.

Sample array:

$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"]
];

Desired result:

[
    ["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"]
]

My current code:

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";
}
108

Answer

Solution:

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

Answer

Solution:

You make it clear in your comment that you originally have the name asfirstname lastname, title, so you just need to sort first, then move the title to the front:

<?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";
}
?>
388

Answer

Solution:

You should prepare your data (Remove all Dr., Ms., etc) and then sort cleaned names only.

842

Answer

Solution:

First of all: Do not count() a constant array in a for loop! You explode() with a non-existent delimiter, so the resulting array has exactly one element which you remove with array_pop(). Then you sort() and implode() an empty array. So you get a random (in this case unchanged) result.

Please check http://php.net/usort

534

Answer

Solution:

You can change your code as

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

Check here : https://eval.in/569467

Output would be :

Array
(
    [0] => Array
        (
            [name] => Mr. aaa
        )

    [1] => Array
        (
            [name] => Dr.    bbb
        )

    [2] => Array
        (
            [name] => Ms.  ccc
        )

)
67

Answer

Solution:

usort() has a more expensive time complexity and will require double the function calls within each iteration. Instead, I recommend usingarray_multisort() and preparing a sorting array with minimal function calls.

Isolate thename column values, then trim the prefix off of every value, then compare those strings. After that, you can effectively sort on the prefixes by sorting on the whole rows.

Code: (Demo)

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

People are also looking for solutions to the problem: php - Sort associative array by corresponding values in another array from largest to smallest

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.