对数组进行排序

PHP 有一些用来排序数组的函数, 这个文档会把它们列出来。

主要区别有:

  • 有些函数基于 array 的键来排序, 而其他的基于值来排序的:$array['key'] = 'value';
  • 排序之后键和值之间的关联关系是否能够保持, 是指排序之后数组的键可能 会被重置为数字型的(0,1,2 ...)。
  • 排序的顺序有:字母表顺序, 由低到高(升序), 由高到低(降序),数字排序,自然排序,随机顺序或者用户自定义排序。
  • 注意:下列的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。
  • 以下函数对于数组中相等的元素,它们在排序后的顺序是未定义的。 (也即相等元素之间的顺序是不稳定的)。

排序函数属性
函数名称 排序依据 数组索引键保持 排序的顺序 相关函数
array_multisort() 键值关联的保持,数字类型的不保持 第一个数组或者由选项指定 array_walk()
asort() 由低到高 arsort()
arsort() 由高到低 asort()
krsort() 由高到低 ksort()
ksort() 由低到高 asort()
natcasesort() 自然排序,大小写不敏感 natsort()
natsort() 自然排序 natcasesort()
rsort() 由高到低 sort()
shuffle() 随机 array_rand()
sort() 由低到高 rsort()
uasort() 由用户定义 uksort()
uksort() 由用户定义 uasort()
usort() 由用户定义 uasort()

User Contributed Notes

roger dot vermeir at nokia dot com 18-Jul-2019 03:32
I tend to use the following code for adding a sort on the keys when different values have the same key:

<?php
$arr
= array();
$res = $db->query("some sql");
while (
$row = $res->fetchRow()) {
 
$key = trim($row[0]);    // I know... 'colname' is better
 
$value = trim($row[1]);
 
$arr[$key] = $value . "_" . sprintf('%09d', $key);    // number
}
arsort($arr);
foreach (
$arr as $key=>$value_and_key) {
  list(
$value, $dummykey) = explode("_", $value_and_key);
  echo
"$key and $value"// reverse sorted by value, then key
}
?>

Appending the key to the value makes arsort a kind of dual sort.
No need for extra user-defined functions...
Roger Vermeir
luca at lauretta dot info 12-Sep-2018 03:47
If you're looking for a quick solution to make usort stable, you could use uksort like in the following example:

<?php

uksort
($array, function ($ak, $bk) use ($array) {
   
$a = $array[$ak];
   
$b = $array[$bk];
    if (
$a['foo'] === $b['foo']) return $ak - $bk;
    return
$a['foo'] > $b['foo'] ? 1 : -1;
});

?>

This works as expected only if the initial indices (keys) of $array are in ascending order.
bizarrus at icloud dot com 30-Jun-2018 12:05
If you wan't to sort JSON based data or an multidimensional object (ascending or descending), you must fetch the array/object keys for sorting - After a sort, you can build a new Object with the correct sorting.

**Example Data:**
<?php
    $json
= [
       
'nameZ' => [
           
'A' => true,
           
'F'    => true,
           
'K'    => true
       
],
       
'nameU' => 'Hello World!',
       
'nameA' => [
           
'subData' => [
               
'resultX' => 1,
               
'resultB' => 4,
               
'resultI' => 6
           
]
        ],
       
'nameK' => [
           
'testing' => true
       
],
    ];
?>

**Function:**
<?php
   
function json_sort(&$json, $ascending = true) {
       
$names = [];
       
       
// Creating a named array for sorting
       
foreach($json AS $name => $value) {
           
$names[] = $name;
        }
       
        if(
$ascending) {
           
asort($names);
        } else {
           
arsort($names);
        }
       
       
$result = [];
       
        foreach(
$names AS $index => $name) {
           
// Sorting Sub-Data
           
if(is_array($json[$name]) || is_object($json[$name])) {
               
json_sort($json[$name], $ascending);
            }
           
           
$result[$name] = $json[$name];
        }
       
       
$json = $result;
    }
?>

**Usage:**
<?php
    json_sort
($json, true); // Ascending order
   
print_r($json);
?>

or

<?php
    json_sort
($json, false); // Descending order
   
print_r($json);
?>

I had written these method for generating HashValues for an API-Request. The HTTP-Request POST the JSON-Data as Body and over GET-Parameter, an digest/token will be appended to validate the JSON-Data (prevent manipulation of the JSON Data).
Hayley Watson 24-Sep-2016 10:55
Stabilizing the sort functions (in this case, usort).

<?php
function stable_usort(&$array, $cmp)
{
   
$i = 0;
   
$array = array_map(function($elt)use(&$i)
    {
        return [
$i++, $elt];
    },
$array);
   
usort($array, function($a, $b)use($cmp)
    {
        return
$cmp($a[1], $b[1]) ?: ($a[0] - $b[0]);
    });
   
$array = array_column($array, 1);
}
?>

Tags each array element with its original position in the array so that when the comparison function returns 0 the tie can be broken to put the earlier element first.
monicse09ku at yahoo dot com 25-Jun-2015 06:57
// takes an array and desired key value and returns an array
// searches through an array for a given key, if found the key that row is made the first row and the other rows are inserted accordingly.
// the facility of this function is to get the value with a specific key of an array as the first value.

/////////////////////////////// function starts //////////////////////////////

function dksort($array, $case){
    if(array_key_exists($case,$array)){
        $a[$case] = $array[$case];
        foreach($array as $key=>$val){
            if($case==$key){

            }else{
                $a[$key] = $array[$key];
            }
        }
    }

    return $a;
}

$d = array(
            '22'=>'jdfhgjfd',
            '33'=>'jdfhgjfd',
            '11'=>'jrtyrjfd',
            '55'=>'jrtydairjfd',
            '77'=>'jopo',
            '99'=>'jrtasajfd',
            '44'=>'jopasdwo',
            '88'=>'hdgatyuyuiuy'
            );

$c = dksort($d, '55');
print_r($c);

////////////////////////// function ends ////////////////////////////////////////
Mssler 23-Jun-2015 09:56
simple example sorting dotted version numbers

     function sortByVersionnumber($a,$b){
         $ta=explode(".",$a); $tb=explode(".",$b);
         foreach ($ta as $k => $v){
             if (isset($tb[$k])){
                 if($ta[$k] > $tb[$k]) {
                     return 1;
                 } elseif($ta[$k] < $tb[$k]) {
                     return -1;
                 }
             }
         }
         return 0;
     }
     function vnksort(&$array){
         uksort($array ,"sortByVersionnumber");
     }
&#34;Matthew Rice&#34; 17-May-2013 08:28
While this may seem obvious, user-defined array sorting functions ( uksort(), uasort(), usort() ) will *not* be called if the array does not have *at least two values in it*.

The following code:                       

<?php

function usortTest($a, $b) {
   
var_dump($a);
   
var_dump($b);
    return -
1;
}

$test = array('val1');
usort($test, "usortTest");

$test2 = array('val2', 'val3');
usort($test2, "usortTest");

?>

Will output:

string(4) "val3"
string(4) "val2"

The first array doesn't get sent to the function.

Please, under no circumstance, place any logic that modifies values, or applies non-sorting business logic in these functions as they will not always be executed.
oculiz at gmail dot com 12-Mar-2011 09:57
Another way to do a case case-insensitive sort by key would simply be:

<?php
uksort
($array, 'strcasecmp');
?>

Since strcasecmp is already predefined in php it saves you the trouble to actually write the comparison function yourself.