2

I have this multidimensional array:

$data[] = array('name' => 'Mini 16', 'id' => 105);
$data[] = array('name' => 'Mini 15', 'id' => 5650);
$data[] = array('name' => 'Mini 100', 'id' => 9889);
$data[] = array('name' => 'Mini 20', 'id' => 587);

I want to order the array by name column sorting naturally, but is difficult for me.

The expected result:

[
    ['name' => 'Mini 15', 'id' => 5650],
    ['name' => 'Mini 16', 'id' => 105],
    ['name' => 'Mini 20', 'id' => 587],
    ['name' => 'Mini 100', 'id' => 9889]
]
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
user1499315
  • 139
  • 1
  • 1
  • 8
  • Check this link http://stackoverflow.com/questions/11267990/how-to-understand-usort-logic and this two links: http://pastebin.com/5J4VAM7S http://pastebin.com/YUcT92CV – Viacheslav Kondratiuk Jul 03 '12 at 16:16
  • Please also check this: http://stackoverflow.com/questions/7839198/array-multisort-with-natural-sort – trante Jul 19 '12 at 22:35

3 Answers3

7

You can use usort() to sort the array by a custom function, and use strnatcmp() to do the natural comparison of two strings like so:

usort( $data, function( $el1, $el2) { return strnatcmp( $el1['name'], $el2['name']); });

So before, your array was this:

array(4) {
  [0]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 16"
    ["id"]=>
    int(105)
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 15"
    ["id"]=>
    int(5650)
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(8) "Mini 100"
    ["id"]=>
    int(9889)
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 20"
    ["id"]=>
    int(587)
  }
}

And now it looks like:

array(4) {
  [0]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 15"
    ["id"]=>
    int(5650)
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 16"
    ["id"]=>
    int(105)
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(7) "Mini 20"
    ["id"]=>
    int(587)
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(8) "Mini 100"
    ["id"]=>
    int(9889)
  }
}

Note that for lower versions of PHP, you won't be able to use an anonymous function, and would instead need something like this:

usort( $data, create_function( '$el1, $el2', 'return strnatcmp( $el1[\'name\'], $el2[\'name\']);' ));
nickb
  • 59,313
  • 13
  • 108
  • 143
  • @user1499315 - You're quite welcome! If my post answered your question, please consider [accepting it](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). Also, welcome to StackOverflow! – nickb Jul 03 '12 at 16:30
3

If you're using PHP 5.4 or newer, you can use array_multisort with the SORT_NATURAL flag. Just follow Example #3 in the http://php.net/manual/en/function.array-multisort.php documentation, but add the SORT_NATURAL option.

Craig Buchek
  • 894
  • 1
  • 8
  • 19
0

As half-answered by Craig, array_multisort() will be more performant than usort() because array_multisort() doesn't make iterated function calls.

Code: (Demo)

array_multisort(array_column($data, 'name'), SORT_NATURAL, $data);
var_export($data);

This is the modern, arrow-function syntax for nickb's answer.

Code (PHP7.4 and higher): (Demo)

usort($data, fn($a, $b) => strnatcmp($a['name'], $b['name']));
var_export($data);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136