takaya030の備忘録

PHP、Laravel、Docker などの話がメインです

Laravel のコレクションの first() で指定するコールバックについて

Laravel 4.2 のコレクション(Collectin)の first() の引数で指定するコールバックについてのメモです。

first() は通常、コレクションの先頭の要素を返しますが、APIリファレンスによると Closure を渡すことでサーチ条件を指定できるようです。

Illuminate\Support\Collection | Laravel API

mixed|null	first(Closure $callback = null, mixed $default = null)
		Get the first item from the collection.

APIリファレンスには Closure の仕様が見当たらなかったので、フレームワークソースコードを確認したら内部で Illuminate\Support\Arr の first() をコールしていました。

vendor/laravel/framework/src/Illuminate/Support/Arr.php

<?php
	/**
	 * Return the first element in an array passing a given truth test.
	 *
	 * @param  array     $array
	 * @param  \Closure  $callback
	 * @param  mixed     $default
	 * @return mixed
	 */
	public static function first($array, $callback, $default = null)
	{
		foreach ($array as $key => $value)
		{
			if (call_user_func($callback, $key, $value)) return $value;
		}

		return value($default);
	}

引数に $key, $value、戻り値に bool を返す Closure のようですね。早速検証してみましょう。

テストコードです。 (app/tests/CollectionTest.php)

<?php
use \Illuminate\Support\Collection;

class CollectionTest extends TestCase {

	/**
	 * 
	 * @group  first
	 */
	public function testFirst()
	{
		$datas = Collection::make(array(10, 20, 30, 40, 50));

		$results = array();
		$results[] = $datas->first();

		$results[] = $datas->first(function($key, $value) {
			return $value == 40;
		});

		$results[] = $datas->first(function($key, $value) {
			return $key == 2;
		});

		var_dump($results);

		$this->assertTrue($results[0] == 10);
		$this->assertTrue($results[1] == 40);
		$this->assertTrue($results[2] == 30);
	}

}

実行結果です。

D:\xampp\htdocs\laravel>phpunit --group first
PHPUnit 4.4.0 by Sebastian Bergmann.

Configuration read from D:\xampp\htdocs\laravel\phpunit.xml

.array(3) {
  [0]=>
  int(10)
  [1]=>
  int(40)
  [2]=>
  int(30)
}


Time: 172 ms, Memory: 6.25Mb

OK (1 test, 3 assertions)

期待した通りの結果になってますね。