php[world] 2019 — 25 years of PHP

# natsort

(PHP 4, PHP 5, PHP 7)

natsortOrdena um array utilizando o algoritmo da "ordem natural"

### Descrição

natsort ( array `&\$array` ) : bool

Essa função é um implementação do algoritmo que ordena strings alfanuméricas da forma como um ser humano faria mantendo associação de chave/valor. Isso é chamado de "ordenação natural". Um exemplo da diferença entre esse algoritmo e o algoritmo com o qual o computador classifica strings (usado em sort()) pode ser visto abaixo:

### Parâmetros

`array`

Retorna `TRUE` em caso de sucesso ou `FALSE` em caso de falha.

### Exemplos

Exemplo #1 Exemplo da natsort()

``` \$array1 = \$array2 = array("img12.png", "img10.png", "img2.png", "img1.png");sort(\$array1);echo "Classificação normal\n";print_r(\$array1);natsort(\$array2);echo "\nClassificação da \"ordem natural\"\n";print_r(\$array2); ```

O exemplo acima irá imprimir:

```Classificação normal
Array
(
 => img1.png
 => img10.png
 => img12.png
 => img2.png
)

Classificação da "ordem natural"
Array
(
 => img1.png
 => img2.png
 => img10.png
 => img12.png
)
```

Para mais informações veja: Martin Pool's » Natural Order String Comparison page.

### Veja Também

• natcasesort() - Ordena um array utilizando o algoritmo da "ordem natural" sem diferenciar maiúsculas e minúsculas
• strnatcmp() - Comparação de strings usando o algoritmo "natural order"
• strnatcasecmp() - Comparação de strings sem diferenciar maiúsculas/minúsculas usando o algoritmo "natural order" add a note

### User Contributed Notes 22 notes

25
wyvern at greywyvern dot com
10 years ago
``` There's no need to include your own API code to natsort an associative array by key.  PHP's in-built functions (other than natsort) can do the job just fine:<?php  uksort(\$myArray, "strnatcmp");?> ```
13
Johan GENNESSON (php at genjo dot fr)
8 years ago
``` Be careful of the new behaviour in 5.2.10 version.See the following sample:<?php\$array = array('1 bis', '10 ter', '0 PHP', '0', '01', '01 Ver', '0 ', '1 ', '1');natsort(\$array);echo '<pre>';print_r(\$array);echo '</pre>';?>5.2.6-1 will output:Array(     => 0     => 0      => 0 OP     => 01     => 01 Ver     => 1     => 1      => 1 bis     => 10 ter)5.2.10 will output:Array(     => 0      => 0     => 1     => 01     => 1      => 01 Ver     => 1 bis     => 10 ter     => 0 OP)Greetings ```
15 years ago
``` Under limited testing, natsort() appears to work well for IP addresses. For my needs, it is far less code than the ip2long()/long2ip() conversion I was using before. ```
flash at minet dot net
15 years ago
``` About the reverse natsort.. Maybe simpler to do :function strrnatcmp (\$a, \$b) {    return strnatcmp (\$b, \$a);} ```
mbirth at webwriters dot de
15 years ago
``` For those who want to natsort a 2d-array on the first element of each sub-array, the following few lines should do the job.<?phpfunction natsort2d(&\$aryInput) {  \$aryTemp = \$aryOut = array();  foreach (\$aryInput as \$key=>\$value) {    reset(\$value);    \$aryTemp[\$key]=current(\$value);  }  natsort(\$aryTemp);  foreach (\$aryTemp as \$key=>\$value) {    \$aryOut[] = \$aryInput[\$key];  }  \$aryInput = \$aryOut;}?> ```
rasmus at flajm dot com
15 years ago
``` To make a reverse function, you can simply:function rnatsort(&\$a){    natsort(\$a);    \$a = array_reverse(\$a, true);} ```
bb7b5b9 at gmail dot com
3 years ago
``` This made me waste a lot of my precious youth ... natsort() is buggy if all numbers don't have the same number of decimal places.(php 5.6.4-4ubuntu6.2)<?php \$different_decimal_places_in_values = array('D'=>'13.59', '14.6' => '14.6', 'C-' => '14.19'); natsort(\$a); var_dump(\$a);/*echoesarray(3) {  'D' =>  string(5) "13.59"  '14.6' =>  string(4) "14.6" <----------- badly ordered  'C-' =>  string(5) "14.19"}*/?>While this <?php \$same_num_decimal_places_in_values = array('D'=>'13.59', '14.6' => '14.60', 'C-' => '14.19'); natsort(\$a); var_dump(\$a);/*echoes array(3) {  'D' =>  string(5) "13.59"  'C-' =>  string(5) "14.19"  '14.6' =>  string(5) "14.60" <--------- that is the correct position}*/?> ```
anonymous at coward dot net
16 years ago
``` Reverse Natsort:  function rnatsort(\$a, \$b) {    return -1 * strnatcmp(\$a, \$b);  }  usort(\$arr, "rnatsort"); ```
ale152
10 years ago
``` Note: negatives number.<?php\$a = array(-5,-2,3,9);natsort(\$a);print_r(\$a);?>Will output:Array (  => -2  => -5  => 3  => 9 ) ```
natcasesort.too
13 years ago
``` I got caught out through naive use of this feature - attempting to sort a list of image filenames from a digital camera, where the filenames are leading zero padded (e.g. DSCF0120.jpg) , will not sort correctly.Maybe the example could be modified to exhibit this behaviour (e.g. set array to -img0120.jpg','IMG0.png', 'img0012.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png)If the example hadn't used images I would have coded it correctly first time around! ```
phpnet at moritz-abraham dot de
14 years ago
``` additional to the code posted by justin at redwiredesign dot com (which I found very usefull) here is a function that sorts complex arrays like this:<?\$array['test0'] = array('main' =>  'a', 'sub' => 'a');\$array['test2'] = array('main' =>  'a', 'sub' => 'b');\$array['test3'] = array('main' =>  'b', 'sub' => 'c');\$array['test1'] = array('main' =>  'a', 'sub' => 'c');\$array['test4'] = array('main' =>  'b', 'sub' => 'a');\$array['test5'] = array('main' =>  'b', 'sub' => 'b');?>or<?\$array = array('main' =>  1, 'sub' => 1);\$array = array('main' =>  1, 'sub' => 2);\$array = array('main' =>  2, 'sub' => 3);\$array = array('main' =>  1, 'sub' => 3);\$array = array('main' =>  2, 'sub' => 1);\$array = array('main' =>  2, 'sub' => 2);?>on one or more columns.the code<? \$array = array_natsort_list(\$array,'main','sub'); ?>will result in \$array being sortet like this:test0,test2,test1,test4,test5,test3or0,2,1,4,5,3.you may even submit more values to the function as it uses a variable parameter list. the function starts sorting on the last and the goes on until the first sorting column is reached.to me it was very usefull for sorting a menu having submenus and even sub-submenus.i hope it might help you too.here is the function:<?function array_natsort_list(\$array) {    // for all arguments without the first starting at end of list    for (\$i=func_num_args();\$i>1;\$i--) {        // get column to sort by        \$sort_by = func_get_arg(\$i-1);        // clear arrays        \$new_array = array();        \$temporary_array = array();        // walk through original array        foreach(\$array as \$original_key => \$original_value) {            // and save only values            \$temporary_array[] = \$original_value[\$sort_by];        }        // sort array on values        natsort(\$temporary_array);        // delete double values        \$temporary_array = array_unique(\$temporary_array);        // walk through temporary array        foreach(\$temporary_array as \$temporary_value) {            // walk through original array            foreach(\$array as \$original_key => \$original_value) {                // and search for entries having the right value                if(\$temporary_value == \$original_value[\$sort_by]) {                    // save in new array                    \$new_array[\$original_key] = \$original_value;                }            }        }        // update original array        \$array = \$new_array;    }    return \$array;}?> ```
h3
13 years ago
``` This function can be very usefull, but in some cases, like if you want to sort a MySQL query result, it's important to keep in mind that MySQL as built'in sorting functions which are way faster than resorting the result using a complex php algorythm, especially with large arrays.ex; 'SELECT * FROM `table` ORDER BY columnName ASC, columnName2 DESC' ```
dotancohen splat gmail spot com
2 years ago
``` As noted in other notes, natsort() does _not_ always return the expected sort order. It seems especially buggy when decimals or 0 padding is used. I've filed this bug report on the issue:https://bugs.php.net/bug.php?id=74672 ```
Malek Mohamed
1 year ago
``` \$array1 = \$array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');natsort(\$array1);echo "\n natsort(); \n";print_r(\$array1);sort(\$array2, SORT_NATURAL);echo "\n sort() with  SORT_NATURAL Option\n";print_r(\$array2);Ouput:natsort();Array(     => IMG0.png     => IMG3.png     => img1.png     => img2.png     => img10.png     => img12.png)sort() with  SORT_NATURAL OptionArray(     => IMG0.png     => IMG3.png     => img1.png     => img2.png     => img10.png     => img12.png)as we can see it's  the same values but not the same keys, and also it's same for sort(\$array1, SORT_NATURAL | SORT_FLAG_CASE); and natcasesort(\$array2) ```
mvs dot php at gmail dot com
4 years ago
``` To naturally sort by array key, the uksort function can be used.<?phpecho "Sort by keys\n";\$smoothie = array('orange' => 1, 'apple' => 1, 'yogurt' => 4, 'banana' => 4);print_r(\$smoothie);uksort( \$smoothie, 'strnatcmp');print_r(\$smoothie)?>Output:Sort by keysArray(    [orange] => 1    [apple]  => 1    [yogurt] => 4    [banana] => 4)Array(    [apple]  => 1    [banana] => 4    [orange] => 1    [yogurt] => 4)See http://php.net/manual/en/function.uksort.php for more information about uksort and http://php.net/strnatcmp for usage of strnatcmp. ```
lacent at gmail dot com
12 years ago
``` there is another rnatsort function lower on the page, but it didn't work in the context i needed it in. reasoning for this:sorting naturally via the keys of an array, but needing to reverse the order.    function rnatsort ( &\$array = array() )     {        \$keys    = array_keys(\$array);        natsort(\$keys);        \$total    = count(\$keys) - 1;        \$temp1    = array();        \$temp2     = array();        // assigning original keys to an array with a backwards set of keys, to use in krsort();        foreach ( \$keys as \$key )        {            \$temp1[\$total] = \$key;            --\$total;        }                ksort(\$temp1);        // setting the new array, with the order from the krsort() and the values of original array.        foreach ( \$temp1 as \$key )         {            \$temp2[\$key] = \$array[\$key];        }        \$array = \$temp2;    } ```
@gmail bereikme
12 years ago
``` Here's a handy function to sort an array on 1 or more columns using natural sort:<?php// Example: \$records = columnSort(\$records, array('name', 'asc', 'addres', 'desc', 'city', 'asc'));\$globalMultisortVar = array();function columnSort(\$recs, \$cols) {    global \$globalMultisortVar;    \$globalMultisortVar = \$cols;    usort(\$recs, 'multiStrnatcmp');    return(\$recs);}function multiStrnatcmp(\$a, \$b) {    global \$globalMultisortVar;    \$cols = \$globalMultisortVar;    \$i = 0;    \$result = 0;    while (\$result == 0 && \$i < count(\$cols)) {        \$result = (\$cols[\$i + 1] == 'desc' ? strnatcmp(\$b[\$cols[\$i]], \$a[\$cols[\$i]]) : \$result = strnatcmp(\$a[\$cols[\$i]], \$b[\$cols[\$i]]));        \$i+=2;    }    return \$result;}?>Greetings,  - John ```
-1
lil at thedreamersmaze dot spam-me-not dot org
13 years ago
``` There's one little thing missing in this useful bit of code posted by mbirth at webwriters dot de:<?phpfunction natsort2d(&\$aryInput) {  \$aryTemp = \$aryOut = array();  foreach (\$aryInput as \$key=>\$value) {   reset(\$value);   \$aryTemp[\$key]=current(\$value);  }  natsort(\$aryTemp);  foreach (\$aryTemp as \$key=>\$value) {   \$aryOut[\$key] = \$aryInput[\$key]; // --------^^^^ add this if you want your keys preserved!  }  \$aryInput = \$aryOut;}?> ```
-2
Christoph
9 years ago
``` Note:The natsort function will sort depending on the operating system, but not depending on either Linux or Windows-based systemsThere's a difference when sorting an array which is generated from the filesystem:Array(     => ./system/kernel/js/01_ui.core.js     => ./system/kernel/js/00_jquery-1.3.2.js     => ./system/kernel/js/02_my.desktop.js)natsort(\$array) will result in two different ways:Case 1: (Debian)Array(     => ./system/kernel/js/00_jquery-1.3.2.js     => ./system/kernel/js/01_ui.core.js     => ./system/kernel/js/02_my.desktop.js)Case 2: (Debian Kernel, but Ubuntu shadowed php-Version)Array(     => ./system/kernel/js/01_ui.core.js     => ./system/kernel/js/02_my.desktop.js     => ./system/kernel/js/00_jquery-1.3.2.js)...so make sure you've named the files beginning with 01, then it works fine. ```
-2
AJenbo
10 years ago
``` natsort might not act like you would expect with zero padding, heres a quick sample. <?php \$array = array('09', '8', '10', '009', '011'); natsort(\$array); ?> /* Array (      => 009      => 011      => 09      => 8      => 10 ) */ ```
-1
Anonymous
13 years ago
``` The last comment should have been posted in doc about (r)sort( ). Indeed, and unfortunately, ORDER BY *does not* perform natural ordering. So, sometimes we *must* do a SQL request followed by natsort( ). ```
-4
justin at redwiredesign dot com
15 years ago
``` One of the things I've needed to do lately is apply natural sorting to a complex array, e.g.:Array(     => Array        (            [ID] = 4            [name] = Fred        )             => Array        (            [ID] = 6            [name] = Bob        ))where I want to sort the parent array by the child's name. I couldn't see a way of doing this using array_walk, so I've written a simple function to do it. Hopefully someone will find this useful:/** * @return Returns the array sorted as required * @param \$aryData Array containing data to sort * @param \$strIndex Name of column to use as an index * @param \$strSortBy Column to sort the array by * @param \$strSortType String containing either asc or desc [default to asc] * @desc Naturally sorts an array using by the column \$strSortBy */function array_natsort(\$aryData, \$strIndex, \$strSortBy, \$strSortType=false){    //    if the parameters are invalid    if (!is_array(\$aryData) || !\$strIndex || !\$strSortBy)        //    return the array        return \$aryData;            //    create our temporary arrays    \$arySort = \$aryResult = array();        //    loop through the array    foreach (\$aryData as \$aryRow)        //    set up the value in the array        \$arySort[\$aryRow[\$strIndex]] = \$aryRow[\$strSortBy];            //    apply the natural sort    natsort(\$arySort);    //    if the sort type is descending    if (\$strSortType=="desc")        //    reverse the array        arsort(\$arySort);            //    loop through the sorted and original data    foreach (\$arySort as \$arySortKey => \$arySorted)        foreach (\$aryData as \$aryOriginal)            //    if the key matches            if (\$aryOriginal[\$strIndex]==\$arySortKey)                //    add it to the output array                array_push(\$aryResult, \$aryOriginal);    //    return the return    return \$aryResult;} ``` 