skip to Main Content

I have the following array items:

[{
    first_name: 'Rebecca'
}, {

    first_name: 'amy'
}, {
    first_name: 'Amy'
}, {

    first_name: 'stacy'
}]

I want the array to be sorted alphabetically according to the first_name property. In a collision where the first_name properties are the same (ie. amy vs Amy), I want the value with the capital letter to come first.

In the above array, the sorted values should be:

[{
    first_name: 'Amy'
}, {

    first_name: 'amy'
}, {
    first_name: 'Rebecca'
}, {

    first_name: 'stacy'
}]

This is the current custom usort() I am using:

usort($users, function($a, $b){
    $first_name_compare = strcasecmp($a['first_name'], $b['first_name']);
    return $first_name_compare;
});

strcasecmp() is supposedly case-insensitive, but I’ve noticed it to be inconsistent. In the above array example, strcasecmp() will sometimes return amy before Amy and vice versa.

What’s a drop in for strcasecmp() in this use case?

2

Answers


  1. When strcasecmp() returns 0, you should fall back on strcmp().

    usort($users, function($a, $b){
        $first_name_compare = strcasecmp($a['first_name'], $b['first_name']);
        if ($first_name_compare == 0) {
            $first_name_compare = strcmp($a['first_name'], $b['first_name']);
        }
        return $first_name_compare;
    });
    
    Login or Signup to reply.
  2. First compare case-insensitively, then to break ties compare case-sensitively.

    ?: is the Elvis operator — if the value in the first evaluation is 0 (falsey), then fallback to the evaluation of the second comparison.

    Code: (Demo)

    usort(
        $users,
        fn($a, $b) => strcasecmp($a['first_name'], $b['first_name'])
            ?: strcmp($a['first_name'], $b['first_name'])
    );
    var_export($users);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search