RitoLabo

Laravel5のCollection(コレクション)クラスで配列・オブジェクトを任意のキーでソート(並び替え)する

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,Collection,sort,helper,5.5,5.4,5.3,5.x

Laravelでデータベースとのやり取り(SELECT)を行った場合、受け取った結果は純粋な連想配列ではなくオブジェクトとして返ってきます。
受け取るデータの並び順に関して、単純にカラム要素であれば、クエリビルダでの問い合わせの際に並び順を指定すればよいだけですが、 例えばデータベースからいくつかのデータを取得し、そのデータにさらに何らかの処理をしてその処理結果に応じてデータをソート(並び替え)したい場合があります。

PHPでは、連想配列(多次元配列)のソート手段としてarray_intersect()という関数が有名ですが、これは純粋な連想配列にのみ有効であり、昨今のPHPフレームワークのように、取得結果にオブジェクトを含む形だとソートは行えません。

Laravelの場合、こういったデータの塊に対して、簡単にソートを行う事が出来ます。
Laravelには、Collection(コレクション)クラスというものが存在しており、配列データに対して様々な処理を行う事が出来ます。
(今回はソートの解説となりますが、それが以外にも様々な処理が行えます。)

[公式]Laravel 5.5 コレクション

コレクションクラスを使用するには、宣言は不要で、collectヘルパを利用するだけという簡単な流れになっていますので、入門、初心者の方でも簡単に使う事が出来ます。
また、今回のデモンストレーションではLaravel5.5を使っていますが、5.4や5.3などの5系でも同様の手順で行えます。

アジェンダ
  1. Collectionクラスのソートメソッド
  2. collectヘルパで並び替えを行う
    1. sortメソッド
    2. sortByとsortByDescメソッド

Collectionクラスのソートメソッド

ソートを行うコレクションのメソッドは以下の3種類です。

sort()
最も簡単なソートです。単純な配列に対して並び替えを行います。
sortBy()
配列やオブジェクトに対してソートを行います。キーを指定し、そのキーに対して昇順(値の小さい順)で並び替えを行います。
sortByDesc()
sortBy()と同じですが、こちらは降順(値の大きい順)で並び替えを行います。

collectヘルパで並び替えを行う

sortメソッド

それでは実際にsortメソッドを使ってみます。
オブジェクトに対する並び替えはsortBy()やsortByDesc()を使いますが、せっかくなのでまずはsort()の使い方です。

// 順不同の数字の配列
$numbers = array(2, 19, 6, 14, 21, 1, 4, 11);

// collectヘルパに配列を渡す
$collection = collect($numbers);

// 並び替えを行う
$sorted = $collection->sort()->all();

// 出力
var_dump($sorted);

配列をcollectヘルパに渡してからsort()を行っています。
ちなみに「->all()」することで、配列で受け取る事が出来ます。つけない場合はオブジェクトで返ります。
結果はこんな感じです。

Array
(
[5] => 1
[0] => 2
[6] => 4
[2] => 6
[7] => 11
[3] => 14
[1] => 19
[4] => 21
)

並び替えが行われていますね。

sortByとsortByDescメソッド

今回のメインはこちらになります。 テストデータなのでただの連想配列になってしまっていますが、データベースから取得したデータを想定(つまり、オブジェクトでもOKという事)しています。

// テストデータ
$books = array(
['id' => 1, 'name' => 'book_1', 'price' => 1000 ],
['id' => 2, 'name' => 'book_2', 'price' => 1200 ],
['id' => 3, 'name' => 'book_3', 'price' => 1300 ],
['id' => 4, 'name' => 'book_4', 'price' => 1400 ],
['id' => 5, 'name' => 'book_5', 'price' => 1500 ],
);

// collectヘルパにデータを渡す
$collection = collect($books);

// priceキーを軸に、金額の大きい順に並び替えを行う
$sorted = $collection->sortByDesc('price');

// 出力
var_dump($sorted);

基本的な流れはsortメソッドと変わりませんが、sortByDescに引数として、並び替えを行うキーを指定しています。
結果です。

Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[4] => Array
(
[id] => 5
[name] => book_5
[price] => 1500
)

[3] => Array
(
[id] => 4
[name] => book_4
[price] => 1400
)

[2] => Array
(
[id] => 3
[name] => book_3
[price] => 1300
)

[1] => Array
(
[id] => 2
[name] => book_2
[price] => 1200
)

[0] => Array
(
[id] => 1
[name] => book_1
[price] => 1000
)

)

)

本の金額である「price」をキーとして、降順(金額の大きい順)に並び替えが行われた事が確認できました。

ちなみに、配列の添え字番号が揃っていない事に気が付くでしょうか? 揃えたい場合には以下のように->values()を追加してください。

$sorted = $collection->sortByDesc('price')->values();

これで番号を振りなおす事が出来ます。

Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => Array
(
[id] => 5
[name] => book_5
[price] => 1500
)

[1] => Array
(
[id] => 4
[name] => book_4
[price] => 1400
)

[2] => Array
(
[id] => 3
[name] => book_3
[price] => 1300
)

[3] => Array
(
[id] => 2
[name] => book_2
[price] => 1200
)

[4] => Array
(
[id] => 1
[name] => book_1
[price] => 1000
)

)

)

まとめ

いかがでしたでしょうか? 冒頭で書いた通り、データベースから取得したデータをさらにPHPで処理した場合に再ソートを行いたい場合などに結構便利です。

Collectionクラスって、Larvelのでもあまりメジャーではないなと感じるのですが、実はかなり便利なヘルパが揃っています。 ソート以外でも色々な事が出来るので是非試してみてください。