David Gard
David Gard

Reputation: 12047

Array keys being sorted incorrectly by 'uksort()' function

I have an array whose keys are in the format [A1] -> [A20], [B1] -> [B20], etc, and I'm trying to sort that array using first ksort() (to get the letters in the correct order) and then uksort().

However, I can't figure out how the uksort() function should be written, and my array keys are coming back in a weird order. Could someone please take a look and advise as to what I am doing wrong? Thanks.

function _sort_selection_keys($a, $b){

    $let_a = substr($a, 0, 1);
    $let_b = substr($b, 0, 1);
    $num_a = intval(substr($a, 1));
    $num_a = intval(substr($b, 1));

    /** Check that the first letter is the same. It should be, as the array has already been through 'ksort()', but it's worth checking any way */
    if($let_a !== $let_b) :
        return strcasecmp($a, $b);
    endif;

    if($num_a > $num_b) :
        return -1;
    elseif($num_a = $num_b) :
        return 0;
    elseif($num_a < $num_b) :
        return 1;
    endif;

}

Upvotes: 1

Views: 953

Answers (5)

xdazz
xdazz

Reputation: 160883

You could just use the strnatcmp function which will fit your needs:

uksort($array, 'strnatcmp');

And another solution metioned by @M8R-1jmw5r

ksort($array, SORT_NATURAL);

Upvotes: 4

M8R-1jmw5r
M8R-1jmw5r

Reputation: 4996

You want to sort your array by the keys in natural order:

ksort($array, SORT_NATURAL);

See ksort().

Natural sort order is:

regular:  A1, A10, A11, A2, A20, A21, ... A3, ...
natural:  A1, A2, A3, ..., A10, A11, ... A20, A21 

Upvotes: 1

phpisuber01
phpisuber01

Reputation: 7715

Without debugging your code there, you can use built-in functionality of the uksort to sort keys alphanumerically with 'strnatcmp'.

Unsorted Array Code

$array = array(
    'A1' => array(),
    'A2' => array(),
    'A3' => array(),
    'A4' => array(),
    'C1' => array(),
    'B2' => array(),
    'B1' => array(),
    'D1' => array(),
    'C2' => array(),
    'B3' => array(),
    'D3' => array(),
    'D2' => array(),
);

uksort($array, 'strnatcmp');

var_dump($array);

Result

array (size=12)
  'A1' => 
    array (size=0)
      empty
  'A2' => 
    array (size=0)
      empty
  'A3' => 
    array (size=0)
      empty
  'A4' => 
    array (size=0)
      empty
  'B1' => 
    array (size=0)
      empty
  'B2' => 
    array (size=0)
      empty
  'B3' => 
    array (size=0)
      empty
  'C1' => 
    array (size=0)
      empty
  'C2' => 
    array (size=0)
      empty
  'D1' => 
    array (size=0)
      empty
  'D2' => 
    array (size=0)
      empty
  'D3' => 
    array (size=0)
      empty

Upvotes: 1

Mark
Mark

Reputation: 11

First, I think all you need to do is change your second "$num_a" line to "$num_b". Other than that, I would simply use strnatcasecmp() on the keys instead of all the dissecting you are attempting.

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191779

Per the documentation for usort:

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

That is, instead of returning true or false, you should return $num_a - $num_b (or do the comparison and return -1, 1, or 0.

Upvotes: 1

Related Questions