Sort array by key, being a string

Asked

Viewed 1,618 times

3

I have a random array containing in its keys, an alphanumeric sequence. Using the function ksort, get the following result:

array(22) {
  ["A1"]=>
  string(2) "A1"
  ["A10"]=>
  string(3) "A10"
  ["A11"]=>
  string(3) "A11"
  ["A12"]=>
  string(3) "A12"
  ["A2"]=>
  string(2) "A2"
  ["A4"]=>
  string(2) "A4"
  ["A5"]=>
  string(2) "A5"
}

However, sorting should prioritize the numerical order of the keys. The expected result is:

array(22) {
  ["A1"]=>
  string(2) "A1"
  ["A2"]=>
  string(3) "A2"
  ["A4"]=>
  string(2) "A4"
  ["A5"]=>
  string(2) "A5"
  ["A10"]=>
  string(2) "A10"
  ["A11"]=>
  string(3) "A11"
  ["A12"]=>
  string(3) "A12"
}
  • The sort made by ksort is correct, because its key is text and not number ...

  • What you want would be to basically separate the string number first ordering by string a apos by number, correct?

  • @Guilhermelautert he wants to order by number looks at the second example which is the output

  • Both are correct. I need to sort both by letter and by number as I exemplified the expected result.

  • @Marcelodeandrade but which the priority the letter or the number?

  • The letter, then the number. A1 A2 A13 B2 B3 B10 etc...

  • The A is fixed? if yes can cut it off and adicioanar after.

  • My example was just a small demo, @rray. The array can contain values from A1-A99 to Z1-Z99.

Show 3 more comments

2 answers

5


You need to sort the keys using the natural sorting algorithm. See the example below:

<?php
$dados = [
    'A1'=> 'A1',
    'A10'=> 'A10',
    'A11'=> 'A11',
    'A12'=> 'A12',
    'A2'=> 'A2',
    'A4'=> 'A4',
    'A5'=> 'A5',
];

uksort($dados, 'strnatcmp');
var_dump($dados);
?>
  • Putz! I’ve never seen this function strnatcmp.

1

Code

$sort = array(
    "A1"    =>  "A1",
    "A10"   =>  "A10",
    "A11"   =>  "A11",
    "A12"   =>  "A12",
    "A2"    =>  "A2",
    "A4"    =>  "A4",
    "A5"    =>  "A5",
    "C12"   =>  "C12",
    "C1"    =>  "C1",
    "B7"    =>  "B7",
    "C52"   =>  "C52",
    "C5"    =>  "C5",
    "B12"   =>  "B12",
);
ksort($sort); // Ordena o array por string

$sortNumber = array();
foreach ($sort as $key => $value){       // quebra o array em bidimencional separando letras de numeros
    $string = preg_replace('~[^a-z]~i', '', $key);
    $number = preg_replace('~\D~', '', $key);

    $sortNumber[$string][$number] = $value;
}

$newArray = array(); 
foreach ($sortNumber as $letter => $options) {  
    ksort($options); // ordena a parte numerica
    foreach ($options as $number => $value) {
        $newArray["{$letter}{$number}"] = $value; // cria novamente o array ordenado por letras e numeros
    }
}

Out

Array
(
    [A1] => A1
    [A2] => A2
    [A4] => A4
    [A5] => A5
    [A10] => A10
    [A11] => A11
    [A12] => A12
    [B7] => B7
    [B12] => B12
    [C1] => C1
    [C5] => C5
    [C12] => C12
    [C52] => C52
)

OBS

There may be failures if the key is composed of letters and numbers and these are mixed. Ex.: A12C8.

  • I’ll check as soon as I can, William. As for the key composition, it is only an even value from A1-A99 to Z1-Z99, so there is no case where they mix.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.