sortBy — コレクションをキー/コールバックでソート

collection
  • カテゴリ: collection
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: Illuminate\Support\Collection::sortBy
  • 関連: sort / sortByDesc / sortKeys / sortKeysDesc / values
  • 変更履歴: なし

要点(TL;DR)

  • 指定キー・ドット記法・コールバックで昇順ソートする
  • 例:$sorted = $items->sortBy('price')->values();
  • 罠:キーは保持される/等価要素の相対順は保証されない/大量データはDB側orderByが安全

概要

sortBy はコレクション要素を、指定したキーやコールバックの戻り値に基づいて昇順に並べ替えます。ドット記法で入れ子要素にも対応。結果は新しいコレクションを返し、元は不変です。表示や集計の直前など、小さな集合の順序付けに向きます。

構文 / シグネチャ

public function sortBy(
    string|callable|array $callback, // キー名 / クロージャ / 複数条件
    int $options = SORT_REGULAR,     // PHPのソートフラグ
    bool $descending = false         // 降順にするか(通常は sortByDesc を推奨)
): Illuminate\Support\Collection
  • 引数(表)
引数必須既定値説明
$callbackstring | callable | array'price' 等のキー名、'user.name' 等のドット記法、fn($v)=>... の戻り値で比較。`[[key,’asc
$optionsintSORT_REGULARSORT_NATURALSORT_FLAG_CASE など PHPのソートフラグ。
$descendingboolfalsetrueで降順。ただし通常は sortByDesc を使用。
  • 戻り値Illuminate\Support\Collectionキー保持。必要なら values() で再採番)
  • 例外/副作用:特になし(ただし LazyCollection では全件をメモリに読み込み)。等価要素の相対順はPHP実装依存で安定しない場合あり。

コレクション固有メモ

  • チェーン可非破壊キー保持
  • LazyCollection: 実行時に収集→通常コレクションへ(遅延性は失われる)
  • 計算量: おおむね O(n log n)

使用例

最小例

<?php

use Illuminate\Support\Collection;

$items = collect([
    ['id' => 1, 'price' => 120],
    ['id' => 2, 'price' => 80],
    ['id' => 3, 'price' => 100],
]);

$sorted = $items->sortBy('price');   // キー保持
$result = $sorted->values()->pluck('id'); // [2, 3, 1]

実務例(複数条件・自然順でタイトル→日付)

<?php

use Illuminate\Support\Collection;

$posts = collect([
    ['id' => 1, 'title' => 'Post 10', 'published_at' => '2025-09-01'],
    ['id' => 2, 'title' => 'Post 2',  'published_at' => '2025-09-02'],
    ['id' => 3, 'title' => 'Post 2',  'published_at' => '2025-08-30'],
]);

// タイトルは「自然順+大文字小文字無視」で昇順、同名なら日付降順
$sorted = $posts
    ->sortBy('title', SORT_NATURAL | SORT_FLAG_CASE)
    ->sortBy([['title', 'asc'], ['published_at', 'desc']]) // 複数条件
    ->values();

$sorted->pluck('id'); // [2, 3, 1]

ネスト(ドット記法)とコールバック

$users = collect([
    ['id'=>1,'profile'=>['name'=>'Yamada','score'=>null]],
    ['id'=>2,'profile'=>['name'=>'sato','score'=>85]],
    ['id'=>3,'profile'=>['name'=>'Sato','score'=>92]],
]);

// 1) ドット記法で名前の自然順
$byName = $users->sortBy('profile.name', SORT_NATURAL | SORT_FLAG_CASE)->values();

// 2) null を最後にして score 昇順(疑似的に配列キーで重み付け)
$byScore = $users->sortBy(fn($u) => [
    is_null($u['profile']['score']),       // false(0) が先、true(1) が後
    $u['profile']['score'] ?? PHP_INT_MAX, // スコア昇順
])->values();

よくある落とし穴・注意

  • キー保持:インデックスが詰まらない → ->values() で再採番。
  • 等価値の順序:同値比較の並びは安定しないことがある。厳密順序が必要なら「複数条件」や重み配列を使う。
  • 文字列の数値比較'10' < '2' になることがある → SORT_NATURAL を使う。
  • 大量データ:アプリ側で並べ替えるとメモリ/CPU負荷が高い → DB クエリで orderBy を使う。
  • LazyCollectionsortBy は遅延を失う(全件収集)。

代替・関連APIとの比較

  • sort:値全体を比較。単純比較ならこちら。キーやドット記法は不可。
  • sortByDesc:降順専用。読みやすさ重視でこちらを推奨。
  • sortKeys / sortKeysDescキーでソート。
  • DBの orderBy:件数が多い場合はDB側で並べ替えるのが原則。

テスト例(Pest)

<?php

it('sorts by key ascending and preserves keys', function () {
    $c = collect([['n'=>2], ['n'=>1]]);
    $sorted = $c->sortBy('n');

    expect($sorted->values()->pluck('n')->all())->toBe([1, 2]);
    // キー保持を確認(元の0,1が保持される)
    expect($sorted->keys()->all())->toBe([1, 0]);
});

トラブルシュート(エラー別)

症状/エラー原因対処
並べ替え後に0,1,2...にならないキー保持仕様->values() で再採番
'10''2' より前に来る文字列比較`SORT_NATURAL
思った順にならない等価値の相対順が不安定複数条件で明示(sortBy([[..., 'asc'], [..., 'desc']])
メモリ不足・遅い大量データをアプリ側でソートDBで orderBy、必要な件数に絞る
LazyCollectionで遅延しないsortBy は全件収集が必要可能ならDB側で並べ替え/件数を絞る

参考リンク

長野県・北アルプス地方在住のフリーランスWebプログラマー。
「落ち着くためのWeb開発」をテーマに、訪れる人が安心して使えるサービスづくりを心がけています。

LaravelやWordPressなどのWebアプリケーション開発を得意とし、技術面の安定性はもちろん、運用後も長く活用できる設計を大切にしています。
静かな山間の暮らしから生まれる視点で、シンプルかつ本質的な解決策をご提案します。

野鳥観察も趣味のひとつで、特にミソサザイ(Wren)に魅力を感じています。
小さな体に反して力強く上向きの尾羽、そして澄んだ鳴き声が遠くまで響く姿に、静かな存在感と芯の強さを感じます。
このサイト名「Laravel Wren」には、そんなミソサザイのように、小さくても確かな価値を届けたいという想いを込めています。

信頼できるパートナーとして、そして気軽に相談できる存在として、あなたのWebプロジェクトをサポートします。

Yudai Tsuyuzakiをフォローする