そろそろ引っ越しをしようかと思い、毎日物件情報サイトを物色しているhikaruです。

物件選びは価格や広さ、築年数、その他様々な側面から比較していく必要があるのでなかなか骨の折れる作業ですね。物件情報がCollectionにまとめられていればサクッと私好み順に並び替えられるのに、としみじみCollectionのありがたみを実感している今日このごろです。

ということで、今回はCollectionのありがたいsort関連のメソッド3つ、sort, sortBy, sortKeysについて解説したいと思います。

サンプルデータ

以降の解説にて使う物件情報を

  • 物件ID
  • 価格(万円)
  • 広さ(㎡)
  • 築年数
  • 駅までの距離(km)

としてコレクションにまとめました、コピペして活用してくださいね。

$houses = collect([
    ['id' => 1, 'price' => 3000, 'size' => 100, 'age' => 20, 'station_distance' => 0.6],
    ['id' => 10, 'price' => 3000, 'size' => 70, 'age' => 3, 'station_distance' => 1.1],
    ['id' => 23, 'price' => 1600, 'size' => 60, 'age' => 13],
    ['id' => 3, 'price' => 1600, 'size' => 50, 'age' => 11, 'station_distance' => 2.0],
]);

sort()

sortメソッドは一次元なコレクションデータを並び替えるのに使用します、例えば築年数を抽出して浅い順に並び替えてみましょう。

>>> $houses->pluck('age', 'id')->sort();
=> Illuminate\Support\Collection {#3330
     all: [
       10 => 3,
       3 => 11,
       23 => 13,
       1 => 20,
     ],
   }

特定の項目を抽出するのはpluckメソッドでしたね、khino氏がLaravel Collection(2) Collectionを返すメソッドで解説しているので忘れてしまった人は復習しておきましょう。

実行結果を見ると、小さい値から大きい値へ順に並び変えられているのが分かります。小から大へ並び変える事を昇順と言います。逆に大から小へ並び替える事を降順と言います。降順に並び替えるにはsortDescメソッドを使います。

>>> $houses->pluck('age', 'id')->sortDesc();
=> Illuminate\Support\Collection {#3396
     all: [
       1 => 20,
       23 => 13,
       3 => 11,
       10 => 3,
     ],
   }

また、この後説明するsortBysortKeysも末尾にDescを付ける事で降順となります。覚えやすいですね!

sortBy()

sortByは指定した引数の項目によって並び替えるメソッドです。例えば、$housesを狭い順に並び替えてみましょう。

>>> $houses->sortBy('size')
=> Illuminate\Support\Collection {#3404
     all: [
       3 => [
         "id" => 3,
         "price" => 1600,
         "size" => 50,
         "age" => 11,
         "station_distance" => 2.0,
       ],
       2 => [
         "id" => 23,
         "price" => 1600,
         "size" => 60,
         "age" => 13,
       ],
       1 => [
         "id" => 10,
         "price" => 3000,
         "size" => 70,
         "age" => 3,
         "station_distance" => 1.1,
       ],
       0 => [
         "id" => 1,
         "price" => 3000,
         "size" => 100,
         "age" => 20,
         "station_distance" => 0.6,
       ],
     ],
   }

ところで、引数で指定した項目がセットされていない場合はどうなるのでしょう?station_distanceで並び替えてみましょう。

>>> $houses->sortBy('station_distance');
=> Illuminate\Support\Collection {#3406
     all: [
       2 => [
         "id" => 23,
         "price" => 1600,
         "size" => 60,
         "age" => 13,
       ],
       0 => [
         "id" => 1,
         "price" => 3000,
         "size" => 100,
         "age" => 20,
         "station_distance" => 0.6,
       ],
       1 => [
         "id" => 10,
         "price" => 3000,
         "size" => 70,
         "age" => 3,
         "station_distance" => 1.1,
       ],
       3 => [
         "id" => 3,
         "price" => 1600,
         "size" => 50,
         "age" => 11,
         "station_distance" => 2.0,
       ],
     ],
   }

station_distanceがセットされていない要素が先頭に来ました。
セットされていない要素は0と同じ扱いなのでしょうか? いえ、そうではありません。セットされていない値はnullとして扱われているのです。そして、マイナス値を含めてソートした場合も先頭にきます。以下のように1次元コレクションで確認すると分かりやすいです。

>>> $col = collect([1, null, -1]);
=> Illuminate\Support\Collection {#3388
     all: [
       1,
       null,
       -1,
     ],
   }
>>> $col->sort()
=> Illuminate\Support\Collection {#3406
     all: [
       1 => null,
       2 => -1,
       0 => 1,
     ],
   }
>>> $col->sortDesc()
=> Illuminate\Support\Collection {#3398
     all: [
       0 => 1,
       2 => -1,
       1 => null,
     ],
   }

これは配列のsort関数と同じ仕様です。nullとは値を持たない事を表現する型の唯一の値であり、他の型(boolean, int, float, stringなど)が混在する配列においては、昇順では先頭に、降順では末尾に並び替えされるのです。

sortKeys()

最後にCollectionのキーによってソートするsortKeysについて見てみましょう。$housesidをキーにしてソートしてみましょう。特定の項目をkeyに指定するにはkeyByメソッドを使います。

>>> $houses->keyBy('id')->sortKeys()
=> Illuminate\Support\Collection {#3414
     all: [
       1 => [
         "id" => 1,
         "price" => 3000,
         "size" => 100,
         "age" => 20,
         "station_distance" => 0.6,
       ],
       3 => [
         "id" => 3,
         "price" => 1600,
         "size" => 50,
         "age" => 11,
         "station_distance" => 2.0,
       ],
       10 => [
         "id" => 10,
         "price" => 3000,
         "size" => 70,
         "age" => 3,
         "station_distance" => 1.1,
       ],
       23 => [
         "id" => 23,
         "price" => 1600,
         "size" => 60,
         "age" => 13,
       ],
     ],
   }

まとめ

以上がCollectionの基本的なsort系メソッドの使い方になります。次回は一歩踏み込んだソートについて解説していきたいと思います。

By hikaru