Help us understand the problem. What is going on with this article?

Laravel でModelの配列を created_at , updated_at で並べ替えたいとき

TL;DR

usort を使って行います

$posts = $user->posts->toArray();
usort($posts, function ($a, $b) {
    if ($a['updated_at'] != $b['updated_at']) {
        return ($a['updated_at'] < $b['updated_at']) ? +1 : -1;
    }

    if ($a['created_at'] != $b['created_at']) {
        return ($a['created_at'] < $b['created_at']) ? +1 : -1;
    }

    return ($a['id'] < $b['id']) ? +1 : -1;
});

デモンストレーション

Postモデルのデータをupdated_at > created_at > id の評価順で降順に並べ替えます

データの準備

  • php artisan make:seeder でSeederを生成
$ php artisan make:seeder PostsTableSeeder
  • 生成したSeederを編集
<?php

use Faker\Factory as Faker;
use App\Post;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('posts')->truncate();
        $faker = Faker::create('en_US');

        for ($i = 0; $i < 5; $i++) {
            $created_at = $faker->dateTime;
            $updated_at = $faker->dateTime;
            while ($created_at > $updated_at) {
                // created_at > updated_atのデータは気持ち悪いため
                $updated_at = $faker->dateTime;
            }

            Post::create([
                "title" => $faker->text(20),
                "content" => $faker->text(100),
                "writer_id" => 1,
                "created_at" => $created_at,
                "updated_at" => $updated_at,
            ]);
        }
    }
}

  • php artisan db:seed でデータ登録
$ php artisan db:seed
Seeding: PostsTableSeeder
Seeded:  PostsTableSeeder (0.12 seconds)
Database seeding completed successfully

usort で並べ替え

PHPには、配列を並べ替える関数が多く用意されています
https://www.php.net/manual/ja/array.sorting.php

今回は複雑な並べ替えをしたいため、usortを使用します
usortは第1引数にソートしたい配列を、第2引数にユーザ定義の比較関数を渡して使用します
この比較関数は比較対象の2つの値を引数に持ち、正の数が返されたときに第1引数が大きい、
負の数が返されたとき第1引数が小さいと判定されます

// Post(オブジェクト)の配列を、Post(配列)の配列に変換する
$posts = $user->posts->toArray();
// 第1引数にPostの配列を、第2引数に$a、$b(を
// 引数に持つコールバックを渡す
usort($posts, function ($a, $b) {
    if ($a['updated_at'] != $b['updated_at']) {
        // 両者のupdated_atが異なる、つまり比較が可能
        return ($a['updated_at'] < $b['updated_at']) ? +1 : -1;
    }

    if ($a['created_at'] != $b['created_at']) {
        return ($a['created_at'] < $b['created_at']) ? +1 : -1;
    }

    // 両者のupdated_at、created_atが同じ場合、idで比較
    return ($a['id'] < $b['id']) ? +1 : -1;
});
  • ソート前のデータ
array:5 [
  0 => array:6 [
    "id" => 1
    "title" => "Quo corrupti autem."
    "content" => "Esse rerum facere excepturi. Possimus eum inventore voluptas necessitatibus."
    "writer_id" => 1
    "created_at" => "1977-07-07 11:20:57"
    "updated_at" => "1994-10-21 08:47:34"
  ]
  1 => array:6 [
    "id" => 2
    "title" => "Id similique magni."
    "content" => "Beatae sed in qui tempora iste omnis. Ab sed alias unde dolorum quae. Enim laborum quos ut."
    "writer_id" => 1
    "created_at" => "1993-07-08 01:36:37"
    "updated_at" => "2010-04-29 20:39:01"
  ]
  2 => array:6 [
    "id" => 3
    "title" => "Maxime rem."
    "content" => "Ut alias nisi sit sunt nulla. Sit illo et necessitatibus dolore eaque placeat nesciunt iste."
    "writer_id" => 1
    "created_at" => "2013-06-27 15:33:04"
    "updated_at" => "2018-04-30 20:57:11"
  ]
  3 => array:6 [
    "id" => 4
    "title" => "A neque quo sit."
    "content" => "Unde explicabo iure est dolor maiores sit. Occaecati assumenda atque exercitationem quos nam omnis."
    "writer_id" => 1
    "created_at" => "2006-04-26 06:04:26"
    "updated_at" => "2009-12-17 18:17:15"
  ]
  4 => array:6 [
    "id" => 5
    "title" => "Ullam quia beatae."
    "content" => "Commodi numquam fugiat eveniet quas. Dolore repellat enim veniam libero."
    "writer_id" => 1
    "created_at" => "2015-04-06 09:17:58"
    "updated_at" => "2020-01-16 19:21:05"
  ]
]
  • ソート後のデータ
array:5 [
  0 => array:6 [
    "id" => 5
    "title" => "Ullam quia beatae."
    "content" => "Commodi numquam fugiat eveniet quas. Dolore repellat enim veniam libero."
    "writer_id" => 1
    "created_at" => "2015-04-06 09:17:58"
    "updated_at" => "2020-01-16 19:21:05"
  ]
  1 => array:6 [
    "id" => 3
    "title" => "Maxime rem."
    "content" => "Ut alias nisi sit sunt nulla. Sit illo et necessitatibus dolore eaque placeat nesciunt iste."
    "writer_id" => 1
    "created_at" => "2013-06-27 15:33:04"
    "updated_at" => "2018-04-30 20:57:11"
  ]
  2 => array:6 [
    "id" => 2
    "title" => "Id similique magni."
    "content" => "Beatae sed in qui tempora iste omnis. Ab sed alias unde dolorum quae. Enim laborum quos ut."
    "writer_id" => 1
    "created_at" => "1993-07-08 01:36:37"
    "updated_at" => "2010-04-29 20:39:01"
  ]
  3 => array:6 [
    "id" => 4
    "title" => "A neque quo sit."
    "content" => "Unde explicabo iure est dolor maiores sit. Occaecati assumenda atque exercitationem quos nam omnis."
    "writer_id" => 1
    "created_at" => "2006-04-26 06:04:26"
    "updated_at" => "2009-12-17 18:17:15"
  ]
  4 => array:6 [
    "id" => 1
    "title" => "Quo corrupti autem."
    "content" => "Esse rerum facere excepturi. Possimus eum inventore voluptas necessitatibus."
    "writer_id" => 1
    "created_at" => "1977-07-07 11:20:57"
    "updated_at" => "1994-10-21 08:47:34"
  ]
]
kshiva1126
都内でプログラマ3年目として働いています。 業務で使用している言語はPHPとたまにJSです。 勉強の中で気づいたことや共有したいことを書いていこうと思っています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした