user1706680
user1706680

Reputation: 1111

Sort array by two keys

I have an array with a couple of names.

$array = Array
(

    [0] => Array
        (
            [fullname] => Skyler White
            [fname] => Skyler
            [lname] => White
        )

    [1] => Array
        (
            [fullname] => Walter White
            [fname] => Walter
            [lname] => White
        )

    [2] => Array
        (
            [fullname] => Marie Schrader
            [fname] => Marie
            [lname] => Schrader
        )

    [3] => Array
        (
            [fullname] => Hank Schrader
            [fname] => Hank
            [lname] => Schrader
        )

    [4] => Array
        (
            [fullname] => Jesse Pinkman
            [fname] => Jesse
            [lname] => Pinkman
        )

)

I’d like the array sorted matching the following criteria:

1) last name lname 2) first name fname

So the ordered array will look like:

$array_ordered = Array
(

    [0] => Array
        (
            [fullname] => Jesse Pinkman
            [fname] => Jesse
            [lname] => Pinkman
        )

    [1] => Array
        (
            [fullname] => Hank Schrader
            [fname] => Hank
            [lname] => Schrader
        )

    [2] => Array
        (
            [fullname] => Marie Schrader
            [fname] => Marie
            [lname] => Schrader
        )


    [3] => Array
        (
            [fullname] => Skyler White
            [fname] => Skyler
            [lname] => White
        )

    [4] => Array
        (
            [fullname] => Walter White
            [fname] => Walter
            [lname] => White
        )

)

Upvotes: 0

Views: 138

Answers (1)

hlscalon
hlscalon

Reputation: 7552

You can use usort and a callback function to make the comparison, using strnatcmp:

function compare($a, $b)
{
    $retLastName = strnatcmp($a['lname'], $b['lname']);
    if(!$retLastName) 
         $retLastName = strnatcmp($a['fname'], $b['fname']);
    return $retLastName;
}

usort($array, 'compare');

@edit

To explain the use of strnatcmp, I will show a little example I think it speaks for itself.

function compareStrcmp($a, $b){
   $retLastName = strcmp($a['lname'], $b['lname']);
   if(!$retLastName) 
        $retLastName = strcmp($a['fname'], $b['fname']);
   return $retLastName;
}

function compare($a, $b){
   $retLastName = strnatcmp($a['lname'], $b['lname']);
   if(!$retLastName) 
        $retLastName = strnatcmp($a['fname'], $b['fname']);
   return $retLastName;
}

$arr1 = $arr2 = array(
       0 => array (
            "fullname" => "Walter White",
            "fname" => "Walter",
            "lname" => "White"
       ) , 
       1 => array (
            "fullname" => "Marie Schrader",
            "fname" => "Marie",
            "lname" => "Schrader"
       ) , 
       2 => array (
            "fullname" => "Walter White 1",
            "fname" => "Walter",
            "lname" => "White 1"
       ) ,
       3 => array (
            "fullname" => "Walter White 10",
            "fname" => "Walter",
            "lname" => "White 10"
       ) ,
       4 => array (
            "fullname" => "Walter White 2",
            "fname" => "Walter",
            "lname" => "White 2"
       )
);
echo "Standard string comparison\n";

usort($arr1, 'compareStrcmp');
print_r($arr1);

echo "\nNatural order string comparison\n";
usort($arr2, "compare");
print_r($arr2);

Output:

Standard string comparison
Array
(
    [0] => Array
        (
            [fullname] => Marie Schrader
            [fname] => Marie
            [lname] => Schrader
        )

    [1] => Array
        (
            [fullname] => Walter White
            [fname] => Walter
            [lname] => White
        )

    [2] => Array
        (
            [fullname] => Walter White 1
            [fname] => Walter
            [lname] => White 1
        )

    [3] => Array
        (
            [fullname] => Walter White 10
            [fname] => Walter
            [lname] => White 10
        )

    [4] => Array
        (
            [fullname] => Walter White 2
            [fname] => Walter
            [lname] => White 2
        )

)

Natural order string comparison
Array
(
    [0] => Array
        (
            [fullname] => Marie Schrader
            [fname] => Marie
            [lname] => Schrader
        )

    [1] => Array
        (
            [fullname] => Walter White
            [fname] => Walter
            [lname] => White
        )

    [2] => Array
        (
            [fullname] => Walter White 1
            [fname] => Walter
            [lname] => White 1
        )

    [3] => Array
        (
            [fullname] => Walter White 2
            [fname] => Walter
            [lname] => White 2
        )

    [4] => Array
        (
            [fullname] => Walter White 10
            [fname] => Walter
            [lname] => White 10
        )

)

As you can see, strcmp puts 'Walter White 10' ahead of 'Walter White 2', what probably would be wrong for us humans. Strnatcmp, on other hand, does not do that, and displays it correctly.

For more info:

PHP example

Natsort algorithm

Upvotes: 2

Related Questions