diff --git a/src/Collection.php b/src/Collection.php index e6413cb..26b7b35 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -10,6 +10,7 @@ namespace Citrus; +use Citrus\Collection\Fetcher; use Citrus\Collection\Filter; use Citrus\Collection\Generator; use Citrus\Collection\JudgeMentor; @@ -36,6 +37,32 @@ public function __construct(array $source) $this->source = $source; } + /************************************************************************** + * Fetcher + **************************************************************************/ + + /** + * 先頭の要素を取得 + * + * @param callable|null $callable + * @return mixed + */ + public function first(callable|null $callable = null): mixed + { + return Fetcher::first($this->source, $callable); + } + + /** + * 最後の要素を取得 + * + * @param callable|null $callable + * @return mixed + */ + public function last(callable|null $callable = null): mixed + { + return Fetcher::last($this->source, $callable); + } + /************************************************************************** * Filter **************************************************************************/ @@ -389,18 +416,4 @@ public function toKeys(): array { return array_keys($this->source); } - - /** - * 一件取得 - * - * @return mixed|null - */ - public function one(): mixed - { - foreach ($this->source as $one) - { - return $one; - } - return null; - } } diff --git a/src/Collection/Fetcher.php b/src/Collection/Fetcher.php new file mode 100644 index 0000000..e850cf9 --- /dev/null +++ b/src/Collection/Fetcher.php @@ -0,0 +1,55 @@ + + * @license http://www.citrus.tk/ + */ + +namespace Citrus\Collection; + +/** + * コレクションメソッド(取得系) + */ +class Fetcher +{ + /** + * 先頭の要素を取得 + * + * @param array $source + * @param callable|null $callable function($value, $key) + * @return mixed + */ + public static function first(array $source, callable|null $callable = null): mixed + { + $filtered = Filter::filter($source, $callable); + $count = Measurer::count($filtered); + // 無ければnull + if ($count === 0) + { + return null; + } + return array_values($filtered)[0]; + } + + /** + * 最後の要素を取得 + * + * @param array $source + * @param callable|null $callable function($value, $key) + * @return mixed + */ + public static function last(array $source, callable|null $callable = null): mixed + { + $filtered = Filter::filter($source, $callable); + $count = Measurer::count($filtered); + // 無ければnull + if ($count === 0) + { + return null; + } + return array_values($filtered)[$count - 1]; + } +} diff --git a/src/Collection/Filter.php b/src/Collection/Filter.php index ef676fb..37f1d91 100644 --- a/src/Collection/Filter.php +++ b/src/Collection/Filter.php @@ -18,12 +18,18 @@ class Filter /** * callable関数の返却値がtrueの場合に積んで返却する * - * @param array $source - * @param callable $callable function($value, $key) + * @param array $source + * @param callable|null $callable function($value, $key) * @return array */ - public static function filter(array $source, callable $callable): array + public static function filter(array $source, callable|null $callable = null): array { + // 無ければそのまま返す + if (is_null($callable)) + { + return $source; + } + $results = []; foreach ($source as $ky => $vl) { diff --git a/src/Collection/Measurer.php b/src/Collection/Measurer.php index 7d28a9d..00de483 100644 --- a/src/Collection/Measurer.php +++ b/src/Collection/Measurer.php @@ -22,7 +22,7 @@ class Measurer * @param callable|null $callable function($value, $key) * @return int */ - public static function count(array $source, callable|null $callable): int + public static function count(array $source, callable|null $callable = null): int { if (!is_null($callable)) { diff --git a/tests/CollectionTest.php b/tests/CollectionTest.php index 1bb5a77..a837733 100644 --- a/tests/CollectionTest.php +++ b/tests/CollectionTest.php @@ -549,17 +549,6 @@ public function sortByProps_ソートした配列を生成して返却() ])->toList()); } - /** - * @test - */ - public function one_一件だけ取得() - { - // 降順にソート - $expected = ['name' => 'a', 'age' => 16]; - // 検算 - $this->assertSame($expected, Collection::stream($this->values)->one()); - } - /** * @test */ @@ -606,6 +595,32 @@ public function isNotEmpty_要素が空ではない() return $value['age'] > 19; })); } + + /** + * @test + */ + public function first_先頭一件取得() + { + // 検算 + $this->assertSame($this->values[0], Collection::stream($this->values)->first()); + // 検算:フィルター + $this->assertSame($this->values[1], Collection::stream($this->values)->first(function ($value, $key) { + return $value['age'] === 11 or $value['age'] === 13; + })); + } + + /** + * @test + */ + public function last_最後一件取得() + { + // 検算 + $this->assertSame($this->values[count($this->values) - 1], Collection::stream($this->values)->last()); + // 検算:フィルター + $this->assertSame($this->values[2], Collection::stream($this->values)->last(function ($value, $key) { + return $value['age'] === 11 or $value['age'] === 13; + })); + } } class CollectionObj