【 php 】usort関数の使い方

## php usort関数の使い方

* phpの配列の中身を並び替える関数はいくつかあります。自分で指定した意図通りに並び替えることができるusort関数というものがあり、使い方がわかりにくかったので、まとめました。

#### usort関数 概要

> 公式：usort — ユーザー定義の比較関数を使用して、配列を値でソートする
> ```bool usort ( array &$array , callable $value_compare_func )```

#### 要するにusort()は...

* 自分で指定した順番で配列の中身を並び替えることができる
* 順番の指定はコールバック関数で行う

呼び出し方の例 (第一引数に配列、第二引数にコールバック関数）

```
usort($orders, 'sortStrlen');
```

----------------------------

#### 解説
注文を配列にし、商品名の長さに応じて、usort関数で並び替えてみます。


```
 $orders = [
     'ナゲット',
     'チキンフィレオ',
     'ポテト',
     'ダブルチーズバーガー',
     'えびフィレオ',
     'コーラ',
 ];
```

並び替えのための、自分で定義した比較関数

```
function sortStrlen($a, $b) {
    if (strlen($a) === strlen($b)) {
        return 0;
    }
    return (strlen($a) < strlen($b)) ? -1 : 1;
};
```


#### sortStrlen()で行なっていること  
* `$orders`配列の中身となる`$a`と`$b`をstrlen関数で文字列の長さで比較をさせています。
* 比較結果に応じて振り分けを行い、0, -1, 1を返しています。


**この0, -1, 1という返り値が、配列を並び替える際に使われる値となります。**  

| 返り値| 詳細 |
|-----------------:|:------------------|
| 0 | `$a`と`$b`の文字列の長さが同じ場合には、0を返すので、順番の並び替えは発生せずそのままとなります。 |
| -1 |`$a`の方が`$b`よりも短い長さの場合には、-1を返すので、`$a`の順番を`$b`より繰り下げることになります。
| 1 | `$a`の方が`$b`よりも長い長さの場合には、1を返すので、`$a`の順番を`$b`より繰り上げることになります。|

* （引数の`$a`と`$b`にはusort()の第一引数で与えた配列の値が入ります）  




**もっと具体的に**


|返り値| $a | $b | 挙動 |
|-----------------|-----------------|------------------|------------------|
|0| ポテト |コーラ |`$a（ポテト）`は`$b（コーラ）`と同じ長さなので、0を返し、`$a（ポテト）`の順番と、`$b（コーラ）`それぞれの順番の並び替えは行いません。|
|-1| ナゲット |ビックマック |`$a（ナゲット）`は`$b（ビックマック）`よりも短いので、-1を返し、`$a（ナゲット）`の順番を、`$b（ビッグマック）`よりも繰り下げます。|
|1| ナゲット|コーラ|`$a（ナゲット）`は`$b（コーラ）`よりも長いので、1を返し、`$a（ナゲット）`の順番を、`$b(コーラ）`よりも繰り上げます。|

* **↑これを配列の全部の値で順々に組み合わせを作成して実行し、順番の上下を行うことで、最終的には長さに応じて並び替えを行なっています**   

実際に`$a`と`$b`の中身と返り値を全て出して見ます。

```
------------------------
$a : ポテト
$b : チキンフィレオ
返り値 : -1
------------------------
$a : コーラ
$b : ポテト
返り値 : 0
------------------------
$a : ポテト
$b : ナゲット
返り値 : -1
------------------------
$a : えびフィレオ
$b : ポテト
返り値 : 1
------------------------
$a : ダブルチーズバーガー
$b : ポテト
返り値 : 1
------------------------
$a : ナゲット
$b : ポテト
返り値 : 1
------------------------
$a : ダブルチーズバーガー
$b : ナゲット
返り値 : 1
------------------------
$a : ダブルチーズバーガー
$b : えびフィレオ
返り値 : 1
------------------------
$a : チキンフィレオ
$b : ダブルチーズバーガー
返り値 : -1
------------------------
$a : ナゲット
$b : チキンフィレオ
返り値 : -1
------------------------
$a : えびフィレオ
$b : ナゲット
返り値 : 1
------------------------
$a : チキンフィレオ
$b : ナゲット
返り値 : 1
------------------------
$a : えびフィレオ
$b : チキンフィレオ
返り値 : -1
------------------------
```


#### コメントを添えてもう一度

```
function sortStrlen($a, $b) {
    // 同じ長さの場合には、順序を変えない
    if (strlen($a) === strlen($b)) {
        return 0;
    }
    // $aの方が短い場合には、$aの順番を$bより繰り下げる
    // $aの方が長い場合には、$aの順番を$bより繰り上げる
    return (strlen($a) < strlen($b)) ? -1 : 1;
};
```



出力例としては以下の通りです。

```
// 出力
echo "並び替える前の注文\n";
foreach ($orders as $key => $value) {
    echo "$key: $value\n";
}


// 並び替え実行
usort($orders, 'sortStrlen');


// 出力
echo "名前の長さで並び替え\n";
foreach ($orders as $key => $value) {
    echo "$key: $value\n";
}
```

---
**実行結果**

```
並び替え前
0: ナゲット
1: チキンフィレオ
2: ポテト
3: ダブルチーズバーガー
4: えびフィレオ
5: コーラ

並び替え後
0: ポテト
1: コーラ
2: ナゲット
3: えびフィレオ
4: チキンフィレオ
5: ダブルチーズバーガー
```
  
#### 要するにusort()は...

* 自分で指定した順番で配列の中身を並び替えることができる
* 順番の指定はコールバック関数で行う

というものでした！

	  
---
**参考 php公式**
* http://php.net/manual/ja/function.usort.php