3
1

More than 1 year has passed since last update.

[Laravel]Collectionにあるnullの値を削除したい!

Posted at

前提

  • Laravel 8.x

やりたいこと

  • Collectionの操作で、

「Collection内にある要素の内、nullの値を消したい!

状況

  • 例えば、orderとuserは1対多の関係であり、users()というメソッドでorderに紐づくuserを取得できる場合、
$users = Order::find($order_id)->users()->get();
dd($users);
  • デバック結果↓
Illuminate\Database\Eloquent\Collection {#** ▼
  #items: array:6 [▼
    0 => App\Models\User {#** ▶}
    1 => App\Models\User {#** ▶}
    2 => null                     // 消したい
    3 => App\Models\User {#** ▶}
    4 => null                     // 消したい
    5 => App\Models\User {#** ▶}
  ]
}
  • こんな感じで要素にnullを含むCollectionとなったとき、値がnullの要素を消したい、という状況

対策案

  • 今回の「やりたいこと」をかなえる手段で一番に浮かんだのは、whereNotNullというCollectionメソッド
    • メソッド名からしていかにも感。

  • ただ、公式を見ると、引数が必要そうな感じ。。。
  • 「使えないかな…」と思ってダメもとで引数無しで以下のように使ってみたところ、、、
$users = Order::find($order_id)->users()
    ->get()
    ->whereNotNull(); // 引数無しで使ってみる
dd($users);
  • デバック結果↓
Illuminate\Database\Eloquent\Collection {#** ▼
  #items: array:4 [▼
    0 => App\Models\User {#** ▶}
    1 => App\Models\User {#** ▶}
    2 => App\Models\User {#** ▶}
    3 => App\Models\User {#** ▶}
  ]
}
  • イケんじゃん笑 ということで一件落着。

  • とはいえ、「どういうことだ?」ということでvender配下のwhereNotNullメソッドの定義場所を漁ると以下のようになってました
public function whereNotNull($key = null)
{
      return $this->where($key, '!==', null);
}

  • 予想通りではあったけど、引数$keyの初期値がnullとしているので、引数なしでも使えるんですねー

余談

同じnull系を扱うwhereNullも同じく$key=nullなので引数無しで使えますね

public function whereNull($key = null)
{
    return $this->whereStrict($key, null);
}

所見

  • こうやってvender配下を見るようになると、意外な使い方できるんだ!って気づきがあってオモロイですね
  • これは個人的な思いですが、whereメソッドって引数にクロージャ使えるようにしたい、って思うときないですかね?
    • 例えば、「とあるコレクション内にあるモデルのリレーション先のプロパティの値と他の値を比較して一致したときに、その値を返す」みたいな処理

whereの使用例(クロージャ―を引数で使えるなら、、、の前提)

  • 先ほどの$usersが以下を持っているとして

    Illuminate\Database\Eloquent\Collection {#** ▼
      #items: array:4 [▼
        0 => App\Models\User {#** ▶}
        1 => App\Models\User {#** ▶}
        2 => App\Models\User {#** ▶}
        3 => App\Models\User {#** ▶}
      ]
    }
    
  • もし、whereでクロージャが使える前提で書くならこんな感じ

for($i=0; $i < 10; $i++){
    $users->where(function($user)use($i){
        return $user->id === $i;
    });
}
dd($users);

これでデバッグの結果が$user→id$iが一致するモデルを返す、見たいに使えたらいいのにな、と思った次第です。

「いやいや、既存のCollectionメソッドで行けるでしょ!」

などツッコミ大歓迎です。どうぞご鞭撻のほどお願いします。

最後までお読みいただきありがとうございました!

3
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
3
1