4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

laravelのCollectionで複数カラムでのソート

Posted at

通常のorderBy

ID降順でソート

$items = [
    [
        'id' => 1,
        'datetime' => '2021-06-01',
    ],
    [
        'id' => 2,
        'datetime' => '2021-06-02',
    ],
    [
        'id' => 3,
        'datetime' => '2021-06-01',
    ],
    [
        'id' => 4,
        'datetime' => '2021-06-02',
    ],
];

$items = collect($items)->sortByDesc('id')->toArray();
dd($items);

結果

array:4 [
  3 => array:2 [
    "id" => 4
    "datetime" => "2021-06-02"
  ]
  2 => array:2 [
    "id" => 3
    "datetime" => "2021-06-01"
  ]
  1 => array:2 [
    "id" => 2
    "datetime" => "2021-06-02"
  ]
  0 => array:2 [
    "id" => 1
    "datetime" => "2021-06-01"
  ]
]

複数カラムでソート

datetime降順、ID昇順でソート


$items = [
    [
        'id' => 1,
        'datetime' => '2021-06-01',
    ],
    [
        'id' => 2,
        'datetime' => '2021-06-02',
    ],
    [
        'id' => 3,
        'datetime' => '2021-06-01',
    ],
    [
        'id' => 4,
        'datetime' => '2021-06-02',
    ],
];

$res = collect($items)->sortBy([
    ['datetime', false], // [カラム名, 昇順でソートするか]
    ['id', true]
])->toArray();
dd($res);

結果

array:4 [
  0 => array:2 [
    "id" => 2
    "datetime" => "2021-06-02"
  ]
  1 => array:2 [
    "id" => 4
    "datetime" => "2021-06-02"
  ]
  2 => array:2 [
    "id" => 1
    "datetime" => "2021-06-01"
  ]
  3 => array:2 [
    "id" => 3
    "datetime" => "2021-06-01"
  ]
]

おまけ

sortBy()の内部ではsortByMany()という関数が呼ばれています。このメソッドの中のis_callable($prop)というところでカラム名がcallableかどうかを確かめています。つまり、dateなどの組み込み関数と同じ名前がソートするカラム名に含まれているとエラーが発生します。気をつけましょう。

    protected function sortByMany(array $comparisons = [])
    {
        $items = $this->items;

        usort($items, function ($a, $b) use ($comparisons) {
            foreach ($comparisons as $comparison) {
                $comparison = Arr::wrap($comparison);

                $prop = $comparison[0];

                $ascending = Arr::get($comparison, 1, true) === true ||
                             Arr::get($comparison, 1, true) === 'asc';

                $result = 0;

                if (is_callable($prop)) {
                    $result = $prop($a, $b);
                } else {
                    $values = [data_get($a, $prop), data_get($b, $prop)];

                    if (! $ascending) {
                        $values = array_reverse($values);
                    }

                    $result = $values[0] <=> $values[1];
                }

                if ($result === 0) {
                    continue;
                }

                return $result;
            }
        });

        return new static($items);
    }
``

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?