LoginSignup
1
1

More than 5 years have passed since last update.

Laravel の Collections で1件目だけ見つけたいループは first() でできる

Posted at

配列から条件にマッチする1件目を取り出したいとき、Laravel の Collection で良い感じな書き方を知らなかったので、filter()->first() みたいな迂遠なやり方や、配列にしてから foreach してました。

ちゃんと Collections や Arr の API を確認してみたら、Collection::first() はコールバックを指定できて、そのものズバリな使い方ができるんですね。すごい便利!

やりたいことは下記のようなイメージで、if ($i % 2) に相当する条件式が複雑だったり重かったりするから、なるべく最小で break できたほうが嬉しいという場面を想定しています。

$odd = function (int ...$args): ?int {
    foreach ($args as $i) {
        if ($i % 2) {
            return $i;
        }
    }
    return null;
};

$odd(...[1, 2, 3, 4, 5]); // 1
$odd(...[2, 3, 4, 5]); // 3
$odd(...[2, 4, 6, 8, 10]); // null

これを Collection で書けば、こんな感じに表現できる。
個人的には、とても自然な表現だと思えます。

$odd = function (int ...$args): ?int {
    return collect($args)->first(function (int $i): bool {
        return ($i % 2);
    });
};

$odd(...[1, 2, 3, 4, 5]); // 1
$odd(...[2, 3, 4, 5]); // 3
$odd(...[2, 4, 6, 8, 10]); // null

ちなみに、最初の例をあえて Laravel の Arr で処理するのであれば、下記のような書き方ができます。(Collection::first() も処理内容としては Arr::first()

$odd = function (int ...$args): ?int {
    return \Illuminate\Support\Arr::first($args, function (int $i): bool {
        return ($i % 2);
    });
};

$odd(...[1, 2, 3, 4, 5]); // 1
$odd(...[2, 3, 4, 5]); // 3
$odd(...[2, 4, 6, 8, 10]); // null
1
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
1
1