1
0

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 でModelの配列を created_at , updated_at で並べ替えたいとき

Posted 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"
  ]
]
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?