PHP 排序 usort 範例教學

by Benmr

前言

最近工作上剛好碰到排序的麻煩問題
這邊就寫下來記錄一下
首先會簡介一下各種排序
最後會針對重點 usort 自訂排序做說明教學

php 官方排序 function

第一類: 用"值 (value)" 排序

  1. 由小到大排序值、且刪除 key => sort
  2. 由小到大排序值、且保留 key => asort
  3. 由大到小排序值、且刪除 key => rsort
  4. 由大到小排序值、且保留 key => arsort

第二類: 用"索引 (key)" 排序

  1. 由小到大排key => ksort
  2. 由大到小排key => krsort

第三類: 自訂排序

加一個前綴 u 在相對應 sort 的前面就好了
以下以 usort 為例

使用 php 官方的自訂排序

如上所說
加一個前綴 u 在相對應 sort 的前面就好了
以下就以 usort 為例

情境一

假設我們有一個 array 長這樣

$unsorted = [
    ['name'   => 'good',
     'sorter' => '1',],

    ['name'   => 'bad',
     'sorter' => '3',],

    ['name'   => 'normal',
     'sorter' => '2',],
];

我們想要照 sorter 由小到大來排的話
就可以用下面的寫法
輸出就是按 sorter 由小到大排
(解釋如註解)

usort($unsorted, function ($a, $b) {
    return $a['sorter'] > $b['sorter'];  
    // 如果 a > b 的話 就會輸出 1,而因為 usort 的 根基是 sort 
    // 意即是照 value 由小到大排序,所以輸出 1 的就會往後排,進而達到目的
});

// output 如下
// array(3) {
//   [0]=>
//   array(2) {
//     ["name"]=>
//     string(4) "good"
//     ["sorter"]=>
//     string(1) "1"
//   }
//   [1]=>
//   array(2) {
//     ["name"]=>
//     string(6) "normal"
//     ["sorter"]=>
//     string(1) "2"
//   }
//   [2]=>
//   array(2) {
//     ["name"]=>
//     string(3) "bad"
//     ["sorter"]=>
//     string(1) "3"
//   }
// }

情境二

一樣的 array 但如果 sorter 有兩個是重複的呢?
比如說這樣:

$unsorted = [
    ['name'   => 'good',
     'sorter' => '1',],

    ['name'   => 'bad',
     'sorter' => '3',],

    ['name'   => 'normal',
     'sorter' => '3',],
];

此時可能就要多一個條件來排了
簡單一點 就多一個 newSorter

$unsorted = [
    ['name'   => 'good',
     'sorter' => '1',
    'newSorter'=> '2'],

    ['name'   => 'bad',
     'sorter' => '3',
    'newSorter'=> '3'],

    ['name'   => 'normal',
     'sorter' => '3',
    'newSorter' => '1'],

    ['name'   => 'hahaha',
     'sorter' => '2',
     'newSorter' => '1'],
];

我們想要按 sorter 來排
但如果 sorter 一樣的話 就用 newSorter 由小到大排
因此寫法如下:

usort($unsorted, function ($a, $b) {
    return $a['sorter'] > $b['sorter'] || ($a['sorter'] == $b['sorter'] && $a['newSorter'] > $b['newSorter']);
}

// output 如下
// array(4) {
//   [0]=>
//   array(3) {
//     ["name"]=>
//     string(4) "good"
//     ["sorter"]=>
//     string(1) "1"
//     ["newSorter"]=>
//     string(1) "2"
//   }
//   [1]=>
//   array(3) {
//     ["name"]=>
//     string(6) "hahaha"
//     ["sorter"]=>
//     string(1) "2"
//     ["newSorter"]=>
//     string(1) "1"
//   }
//   [2]=>
//   array(3) {
//     ["name"]=>
//     string(6) "normal"
//     ["sorter"]=>
//     string(1) "3"
//     ["newSorter"]=>
//     string(1) "1"
//   }
//   [3]=>
//   array(3) {
//     ["name"]=>
//     string(3) "bad"
//     ["sorter"]=>
//     string(1) "3"
//     ["newSorter"]=>
//     string(1) "3"
//   }
// }

也可以寫成下面這樣
基本上可以理解成輸出 1 的話就往後排 (因為 usort 的基底是 sort)

if ($a['sorter'] > $b['sorter'] || ($a['sorter'] == $b['sorter'] && $a['newSorter'] > $b['newSorter'])) {
    return 1;
} elseif ($a['sorter'] < $b['sorter']) {
    return -1;
} else {
    return 0;
}

以上!
網路上找了很久還是找不到完整對 usort 的說明
希望這篇文章對大家有幫助
有問題的話可以再留言喔!

You may also like

Leave a Comment