Arr::first

Returns the first array element passing a truth test, or a default when nothing matches.

Signature
public static function first($array, ?callable $callback = null, $default = null)
  • Added in Laravel 5.0

Parameters

ParameterTypeDescription
$$arrayiterableThe array or other iterable to search.
$$callbackoptionalcallable|null= nullA truth test receiving the value and then the key. When null, the first element is returned.
$$defaultoptionalmixed= nullReturned when the array is empty or nothing matches. A Closure is invoked only at that point.

Return value

mixedThe first value satisfying the callback, the first value when no callback is given, or the resolved default when nothing matches.

Arr::first does double duty. With no callback it hands back the first element of an array — useful when the keys are strings and $array[0] is meaningless. With a callback it becomes a find: it returns the first value for which the test is true, and the default when nothing matches.

When to reach for it

Use it in place of a foreach with a break, and in place of array_search when you want the matching value rather than its key. It is also the clean way to read one element out of an associative array whose first key you do not know, which reset() does only by moving the internal pointer.

What trips people up

The callback receives the value first and the key second, which is the opposite order of array_filter with ARRAY_FILTER_USE_BOTH. A matched value of null, false or 0 is indistinguishable from no match if you only check truthiness of the result, so compare against your default explicitly. And because the default is passed through value(), a Closure default is called only when nothing matches — which is exactly what you want for an expensive fallback, but means a Closure you intended to return as a value gets invoked.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Finding the first order in a list over a given total without writing a loop.
  • Reading one element from an associative array whose first key is unknown.
  • Falling back to an expensive computed default only when no element matches.

Frequently asked questions

How is Arr::first different from array_search?

Arr::first returns the matching value and takes a callback, while array_search returns the key and matches by equality against a fixed needle.

What order does the Arr::first callback receive its arguments in?

The value comes first and the key second, which is the reverse of array_filter with ARRAY_FILTER_USE_BOTH.

How do I tell a matched null apart from no match at all?

Pass a unique sentinel value, such as a fresh object, as the third argument and compare the result to it with ===, since a matched null or 0 looks identical to a null default.

More examples

Reading from an associative array

Prints "The email field is required." The outer call returns the first message bag without needing to know that the first key is 'email', and the inner call pulls the first message out of it. reset() would do the same but mutates the array's internal pointer.

Example · php
<?php

use Illuminate\Support\Arr;

$errors = [
    'email' => ['The email field is required.'],
    'name' => ['The name field is required.'],
];

echo Arr::first(Arr::first($errors)), "\n";

The callback receives value then key

Prints [0.92,"eur"]. The first argument to the callback is the value and the second is the key, the reverse of what array_filter with ARRAY_FILTER_USE_BOTH passes. Arr::first always returns the value, so search the keys array when it is the key you want.

Example · php
<?php

use Illuminate\Support\Arr;

$rates = ['usd' => 1.0, 'eur' => 0.92, 'gbp' => 0.79];

$firstUnder = Arr::first($rates, function (float $value, string $key) {
    return $value < 1.0;
});

$firstKey = Arr::first(array_keys($rates), fn (string $code) => $code !== 'usd');

echo json_encode([$firstUnder, $firstKey]), "\n";

Distinguishing a falsy match from no match

Prints bool(false) then int(0). The match really was found and its value is 0, so a plain if ($found) test would wrongly report a miss. Passing a unique sentinel object as the default is the reliable way to tell "matched a falsy value" from "matched nothing".

Example · php
<?php

use Illuminate\Support\Arr;

$readings = ['a' => 5, 'b' => 0, 'c' => 3];

$sentinel = new stdClass;
$found = Arr::first($readings, fn (int $v) => $v < 1, $sentinel);

var_dump($found === $sentinel);
var_dump($found);

Discussion

  • Be the first to comment on this lesson.