From c937d452a1b259a4b611ee72b67c2cb8dedaf818 Mon Sep 17 00:00:00 2001 From: "kouhei.takemoto" Date: Sat, 29 Jun 2024 18:02:26 +0900 Subject: [PATCH] =?UTF-8?q?count,isEmpty,isNotEmpt=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 16 +- composer.json | 6 +- phpinsights.php | 76 ++++----- src/Collection.php | 281 ++++++++++++++++----------------- src/Collection/Filter.php | 16 +- src/Collection/Generator.php | 20 +-- src/Collection/JudgeMentor.php | 41 +++++ src/Collection/Measurer.php | 34 ++++ src/Collection/Register.php | 6 +- src/Collection/Scanner.php | 37 ++--- src/Collection/Sorter.php | 13 +- tests/CollectionTest.php | 98 +++++++----- 12 files changed, 358 insertions(+), 286 deletions(-) create mode 100644 src/Collection/JudgeMentor.php create mode 100644 src/Collection/Measurer.php diff --git a/Makefile b/Makefile index 159303c..5479c34 100644 --- a/Makefile +++ b/Makefile @@ -5,25 +5,23 @@ define highlight @echo "\033[1;32m$1\033[0m" endef -.PHONY: test_all -test_all: +.PHONY: test +test: @./vendor/bin/phpunit .PHONY: composer_reload composer_reload: - @composer clear-cache --no-interaction - @composer update -vv --no-interaction - @composer dump-autoload --no-interaction + @composer clear-cache + @composer update -vv + @composer dump-autoload .PHONY: composer_develop composer_develop: - @composer clear-cache --no-interaction - @composer install -vv --no-interaction --dev --prefer-dist --optimize-autoloader + @composer install -vv --dev --prefer-dist --optimize-autoloader .PHONY: composer_public composer_public: - @composer clear-cache --no-interaction - @composer install -vv --no-interaction --no-dev --prefer-dist --optimize-autoloader + @composer install -vv --no-dev --prefer-dist --optimize-autoloader .PHONY: composer_check composer_check: diff --git a/composer.json b/composer.json index 941beb8..8068f51 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,9 @@ ], "require": {}, "require-dev": { - "php": "^7.3", - "phpunit/phpunit": "^8.4", - "nunomaduro/phpinsights": "^v1.13" + "php": "^8.3", + "phpunit/phpunit": "^10.5", + "nunomaduro/phpinsights": "^v2.11" }, "autoload": { "psr-4": { diff --git a/phpinsights.php b/phpinsights.php index 9558079..694047f 100644 --- a/phpinsights.php +++ b/phpinsights.php @@ -5,60 +5,57 @@ return [ 'preset' => 'default', 'exclude' => [ - // 'path/to/directory-or-file' ], 'add' => [ - // ExampleMetric::class => [ - // ExampleInsight::class, - // ] NunoMaduro\PhpInsights\Domain\Metrics\Code\Code::class => [ + // Code SlevomatCodingStandard\Sniffs\ControlStructures\RequireYodaComparisonSniff::class, ], ], 'remove' => [ - // ExampleInsight::class, - SlevomatCodingStandard\Sniffs\ControlStructures\DisallowShortTernaryOperatorSniff::class, + // Code + NunoMaduro\PhpInsights\Domain\Insights\ForbiddenGlobals::class, + SlevomatCodingStandard\Sniffs\Classes\ForbiddenPublicPropertySniff::class, + NunoMaduro\PhpInsights\Domain\Sniffs\ForbiddenSetterSniff::class, + PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer::class, + PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\UselessOverridingMethodSniff::class, + SlevomatCodingStandard\Sniffs\Commenting\UselessInheritDocCommentSniff::class, SlevomatCodingStandard\Sniffs\ControlStructures\DisallowYodaComparisonSniff::class, + SlevomatCodingStandard\Sniffs\ControlStructures\LanguageConstructWithParenthesesSniff::class, + SlevomatCodingStandard\Sniffs\Functions\StaticClosureSniff::class, SlevomatCodingStandard\Sniffs\PHP\UselessParenthesesSniff::class, SlevomatCodingStandard\Sniffs\TypeHints\DisallowArrayTypeHintSyntaxSniff::class, - SlevomatCodingStandard\Sniffs\TypeHints\UselessConstantTypeHintSniff::class, - PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer::class, - PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer::class, - PhpCsFixer\Fixer\Phpdoc\PhpdocInlineTagFixer::class, - PhpCsFixer\Fixer\Phpdoc\PhpdocSeparationFixer::class, - PhpCsFixer\Fixer\Phpdoc\AlignMultilineCommentFixer::class, - PHP_CodeSniffer\Standards\PSR2\Sniffs\ControlStructures\ElseIfDeclarationSniff::class, - PHP_CodeSniffer\Standards\Generic\Sniffs\Formatting\SpaceAfterCastSniff::class, + SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff::class, + SlevomatCodingStandard\Sniffs\TypeHints\PropertyTypeHintSniff::class, + SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSniff::class, + + // Architecture + NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses::class, NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits::class, SlevomatCodingStandard\Sniffs\Classes\SuperfluousExceptionNamingSniff::class, - NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses::class, - SlevomatCodingStandard\Sniffs\Commenting\UselessInheritDocCommentSniff::class, - SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff::class, + + // Style + PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace\ArbitraryParenthesesSpacingSniff::class, + PHP_CodeSniffer\Standards\PSR2\Sniffs\ControlStructures\ElseIfDeclarationSniff::class, ], 'config' => [ - // ExampleInsight::class => [ - // 'key' => 'value', - // ], - ObjectCalisthenics\Sniffs\NamingConventions\ElementNameMinimalLengthSniff::class => [ - 'minLength' => 3, - 'allowedShortNames' => ['i', 'id', 'to', 'up', 'ky', 'vl', 'e'], - ], - PhpCsFixer\Fixer\CastNotation\CastSpacesFixer::class => [ - 'space' => 'none', + // Architecture + SlevomatCodingStandard\Sniffs\Functions\FunctionLengthSniff::class => [ + 'maxLinesLength' => 32, ], + + // Style PhpCsFixer\Fixer\Basic\BracesFixer::class => [ - 'allow_single_line_closure' => true, + 'allow_single_line_closure' => false, 'position_after_anonymous_constructs' => 'same', 'position_after_control_structures' => 'next', 'position_after_functions_and_oop_constructs' => 'next', ], - SlevomatCodingStandard\Sniffs\Commenting\DocCommentSpacingSniff::class => [ - 'linesCountBeforeFirstContent' => 0, - 'linesCountBetweenDescriptionAndAnnotations' => 1, - 'linesCountBetweenDifferentAnnotationsTypes' => 0, - 'linesCountBetweenAnnotationsGroups' => 0, - 'linesCountAfterLastContent' => 0, - 'annotationsGroups' => [], + PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer::class => [ + 'operators' => [ + '=>' => 'align_single_space', + ], + 'default' => 'single_space', // default fix strategy: possibles values ['align', 'align_single_space', 'align_single_space_minimal', 'single_space', 'no_space', null] ], PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer::class => [ 'tokens' => [], // possibles values ['break', 'case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'return', 'square_brace_block', 'switch', 'throw', 'use', 'use_trait'] @@ -68,8 +65,13 @@ 'absoluteLineLimit' => 120, 'ignoreComments' => true, ], - \ObjectCalisthenics\Sniffs\Files\FunctionLengthSniff::class => [ - 'maxLength' => 32, - ] + SlevomatCodingStandard\Sniffs\Commenting\DocCommentSpacingSniff::class => [ + 'linesCountBeforeFirstContent' => 0, + 'linesCountBetweenDescriptionAndAnnotations' => 1, + 'linesCountBetweenDifferentAnnotationsTypes' => 0, + 'linesCountBetweenAnnotationsGroups' => 0, + 'linesCountAfterLastContent' => 0, + 'annotationsGroups' => [], + ], ], ]; diff --git a/src/Collection.php b/src/Collection.php index 2a6dcd6..e6413cb 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -12,6 +12,8 @@ use Citrus\Collection\Filter; use Citrus\Collection\Generator; +use Citrus\Collection\JudgeMentor; +use Citrus\Collection\Measurer; use Citrus\Collection\Register; use Citrus\Collection\Scanner; use Citrus\Collection\Sorter; @@ -21,265 +23,272 @@ */ class Collection { - /** @var iterable データソース */ - protected $source; - - + /** @var array データソース */ + protected array $source; /** * constructor. * - * @param iterable $source + * @param array $source */ - public function __construct(iterable $source) + public function __construct(array $source) { $this->source = $source; } - - /************************************************************************** - * Register + * Filter **************************************************************************/ /** - * callable関数がnull以外の値を返した場合、値を積んで返却する + * callable関数の返却値がtrueの場合に積んで返却する * * @param callable $callable * @return $this */ - public function append(callable $callable): self + public function filter(callable $callable): self { - $this->source = Register::append($this->source, $callable); + $this->source = Filter::filter($this->source, $callable); return $this; } - - - /************************************************************************** - * Scanner - **************************************************************************/ - /** - * callable関数を適用した内容を積んで返却する + * callable関数がの返却値がtrueの場合に削除して返却する * * @param callable $callable * @return $this */ - public function map(callable $callable): self + public function remove(callable $callable): self { - $this->source = Scanner::map($this->source, $callable); - return $this; + // false の場合に残せば良いので filter の逆 + return $this->filter(function ($vl, $ky) use ($callable) { + return (false === $callable($vl, $ky)); + }); } - - /** - * 指定メソッドを実行した適用した内容を積んで返却する + * 値がnullではないものを返却する * - * @param string $method_name * @return $this */ - public function mapExecMethod(string $method_name): self + public function notNull(): self { - $this->source = Scanner::map($this->source, function ($vl) use ($method_name) { - // メソッドが存在する場合に実行する - if (true === method_exists($vl, $method_name)) - { - $vl->$method_name(); - } - return $vl; + return $this->filter(function ($vl) { + return (false === is_null($vl)); }); - return $this; } - - /** - * callable関数を適用した内容を積んで返却する - * keyを指定する + * 値がnullではないものを返却する * - * @param callable $callable + * @param string $property キー名称 + * @param string|int|callable $expr 値かcallableで遅延実行 * @return $this */ - public function mapWithKey(callable $callable): self + public function where(string $property, string|int|callable $expr): self { - $this->source = Scanner::mapWithKey($this->source, $callable); + $this->source = Filter::where($this->source, $property, $expr); return $this; } + /************************************************************************** + * Generator + **************************************************************************/ + /** + * 配列設定して、コレクションを生成 + * + * @param array $source + * @return $this + */ + public static function stream(array $source): self + { + return Generator::stream($source); + } /** - * callable関数を適用した内容を積んで返却する - * keyを維持する + * 指定した範囲でcallable関数を実行し、コレクションを生成 * + * @param int $start 開始 + * @param int $end 終了 * @param callable $callable * @return $this */ - public function keyMap(callable $callable): self + public static function range(int $start, int $end, callable $callable): self { - $this->source = Scanner::keyMap($this->source, $callable); - return $this; + return Generator::range($start, $end, $callable); } - - /** - * コレクションにchunkを適用する + * 指定した回数でcallable関数を実行し、コレクションを生成 * - * @param int $chunk いくつずつに分割するか - * @param bool $preserve_keys true:キーを維持する + * @param int $count 回数 + * @param callable $callable * @return $this */ - public function chunk(int $chunk, bool $preserve_keys = false): self + public static function repeat(int $count, callable $callable): self { - $this->source = array_chunk($this->source, $chunk, $preserve_keys); - return $this; + // 範囲は1から$count + return Generator::range(1, $count, $callable); } - - /** - * 多次元コレクションを一次元にする + * 両方の要素を残したいい感じの配列マージ * - * @param int|null $depth 再起回数の指定 - * @param bool $preserve_keys true:キーを維持する、キーが重複する場合は後勝ちする + * 同じ要素がある場合はあとが優先 + * + * @param array $values * @return $this */ - public function flatten(int $depth = 1, bool $preserve_keys = false): self + public function betterMerge(array $values): self { - $this->source = Scanner::flatten($this->source, $depth, $preserve_keys); + $this->source = Generator::betterMergeRecursive($this->source, $values); return $this; } - - /************************************************************************** - * Filter + * JudgeMentor **************************************************************************/ /** - * callable関数の返却値がtrueの場合に積んで返却する + * 要素が空である * - * @param callable $callable - * @return $this + * @param callable|null $callable function($value, $key) + * @return bool */ - public function filter(callable $callable): self + public function isEmpty(callable|null $callable = null): bool { - $this->source = Filter::filter($this->source, $callable); - return $this; + return JudgeMentor::isEmpty($this->source, $callable); } - - /** - * callable関数がの返却値がtrueの場合に削除して返却する + * 要素が空ではない * - * @param callable $callable - * @return $this + * @param callable|null $callable function($value, $key) + * @return bool */ - public function remove(callable $callable): self + public function isNotEmpty(callable|null $callable = null): bool { - // false の場合に残せば良いので filter の逆 - return $this->filter(function ($vl, $ky) use ($callable) { - return (false === $callable($vl, $ky)); - }); + return JudgeMentor::isNotEmpty($this->source, $callable); } - + /************************************************************************** + * Measurer + **************************************************************************/ /** - * 値がnullではないものを返却する + * 総素数 * - * @return $this + * @param callable|null $callable function($value, $key) + * @return int */ - public function notNull(): self + public function count(callable|null $callable = null): int { - return $this->filter(function ($vl) { - return (false === is_null($vl)); - }); + return Measurer::count($this->source, $callable); } - + /************************************************************************** + * Register + **************************************************************************/ /** - * 値がnullではないものを返却する + * callable関数がnull以外の値を返した場合、値を積んで返却する * - * @param string $property キー名称 - * @param string|int|callable $expr 値かcallableで遅延実行 + * @param callable $callable * @return $this */ - public function where(string $property, $expr): self + public function append(callable $callable): self { - $this->source = Filter::where($this->source, $property, $expr); + $this->source = Register::append($this->source, $callable); return $this; } - - /************************************************************************** - * Generator + * Scanner **************************************************************************/ /** - * 配列設定して、コレクションを生成 + * callable関数を適用した内容を積んで返却する * - * @param iterable $source + * @param callable $callable * @return $this */ - public static function stream(iterable $source): self + public function map(callable $callable): self { - return Generator::stream($source); + $this->source = Scanner::map($this->source, $callable); + return $this; } - + /** + * 指定メソッドを実行した適用した内容を積んで返却する + * + * @param string $method_name + * @return $this + */ + public function mapExecMethod(string $method_name): self + { + $this->source = Scanner::map($this->source, function ($vl) use ($method_name) { + // メソッドが存在する場合に実行する + if (true === method_exists($vl, $method_name)) + { + $vl->$method_name(); + } + return $vl; + }); + return $this; + } /** - * 指定した範囲でcallable関数を実行し、コレクションを生成 + * callable関数を適用した内容を積んで返却する + * keyを指定する * - * @param int $start 開始 - * @param int $end 終了 * @param callable $callable * @return $this */ - public static function range(int $start, int $end, callable $callable): self + public function mapWithKey(callable $callable): self { - return Generator::range($start, $end, $callable); + $this->source = Scanner::mapWithKey($this->source, $callable); + return $this; } - - /** - * 指定した回数でcallable関数を実行し、コレクションを生成 + * callable関数を適用した内容を積んで返却する + * keyを維持する * - * @param int $count 回数 * @param callable $callable * @return $this */ - public static function repeat(int $count, callable $callable): self + public function keyMap(callable $callable): self { - // 範囲は1から$count - return Generator::range(1, $count, $callable); + $this->source = Scanner::keyMap($this->source, $callable); + return $this; } - - /** - * 両方の要素を残したいい感じの配列マージ - * - * 同じ要素がある場合はあとが優先 + * コレクションにchunkを適用する * - * @param iterable $values + * @param int $chunk いくつずつに分割するか + * @param bool $preserve_keys true:キーを維持する * @return $this */ - public function betterMerge(iterable $values): self + public function chunk(int $chunk, bool $preserve_keys = false): self { - $this->source = Generator::betterMergeRecursive($this->source, $values); + $this->source = array_chunk($this->source, $chunk, $preserve_keys); return $this; } - + /** + * 多次元コレクションを一次元にする + * + * @param int|null $depth 再起回数の指定 + * @param bool|null $preserve_keys true:キーを維持する、キーが重複する場合は後勝ちする + * @return $this + */ + public function flatten(int|null $depth = 1, bool|null $preserve_keys = false): Collection + { + $this->source = Scanner::flatten($this->source, $depth, $preserve_keys); + return $this; + } /************************************************************************** * Sorter @@ -299,8 +308,6 @@ public function sortBy(callable $callable): self return $this; } - - /** * プロパティを指定してソートする * @@ -320,8 +327,6 @@ public function sortByProp(string $property, bool $ascending = true): self return $this; } - - /** * プロパティを複数指定してソートする * @@ -351,8 +356,6 @@ public function sortByProps(array $properties): self return $this; } - - /************************************************************************** * Exporter **************************************************************************/ @@ -360,45 +363,39 @@ public function sortByProps(array $properties): self /** * 出力 * - * @return iterable + * @return array */ - public function toList(): iterable + public function toList(): array { return $this->source; } - - /** * 出力(値だけ) * - * @return iterable + * @return array */ - public function toValues(): iterable + public function toValues(): array { return array_values($this->source); } - - /** * 出力(キーだけ) * - * @return iterable + * @return array */ - public function toKeys(): iterable + public function toKeys(): array { return array_keys($this->source); } - - /** * 一件取得 * * @return mixed|null */ - public function one() + public function one(): mixed { foreach ($this->source as $one) { diff --git a/src/Collection/Filter.php b/src/Collection/Filter.php index fe5c588..ef676fb 100644 --- a/src/Collection/Filter.php +++ b/src/Collection/Filter.php @@ -18,11 +18,11 @@ class Filter /** * callable関数の返却値がtrueの場合に積んで返却する * - * @param iterable $source - * @param callable $callable function($key, $value) - * @return iterable + * @param array $source + * @param callable $callable function($value, $key) + * @return array */ - public static function filter(iterable $source, callable $callable): iterable + public static function filter(array $source, callable $callable): array { $results = []; foreach ($source as $ky => $vl) @@ -35,17 +35,15 @@ public static function filter(iterable $source, callable $callable): iterable return $results; } - - /** * 指定プロパティと引数値が一致した場合に積む * - * @param iterable $source ソース + * @param array $source ソース * @param string $property プロパティ名称 * @param string|int|callable $expr 値かcallableで遅延実行 - * @return iterable + * @return array */ - public static function where(iterable $source, string $property, $expr): iterable + public static function where(array $source, string $property, string|int|callable $expr): array { $results = []; foreach ($source as $ky => $vl) diff --git a/src/Collection/Generator.php b/src/Collection/Generator.php index 357827d..989a7f2 100644 --- a/src/Collection/Generator.php +++ b/src/Collection/Generator.php @@ -20,16 +20,14 @@ class Generator /** * 配列設定して、コレクションを生成 * - * @param iterable $source + * @param array $source * @return Collection */ - public static function stream(iterable $source): Collection + public static function stream(array $source): Collection { return new Collection($source); } - - /** * 指定した範囲でcallable関数を実行し、コレクションを生成 * @@ -48,22 +46,20 @@ public static function range(int $start, int $end, callable $callable): Collecti return new Collection($results); } - - /** * 両方の要素を残したいい感じの配列マージ - * * 同じ要素がある場合はあとが優先 * - * @param iterable $array1 - * @param iterable $array2 - * @return iterable + * @param array $array1 + * @param array $array2 + * @return array */ - public static function betterMergeRecursive(iterable $array1, iterable $array2): iterable + public static function betterMergeRecursive(array $array1, array $array2): array { foreach ($array2 as $ky => $vl) { - $array1[$ky] = (true === is_array($vl) + $array1[$ky] = ( + true === is_array($vl) ? self::betterMergeRecursive(($array1[$ky] ?? []), $array2[$ky]) // 配列の場合 : $array2[$ky] // 配列以外の場合 ); diff --git a/src/Collection/JudgeMentor.php b/src/Collection/JudgeMentor.php new file mode 100644 index 0000000..7f68256 --- /dev/null +++ b/src/Collection/JudgeMentor.php @@ -0,0 +1,41 @@ + + * @license http://www.citrus.tk/ + */ + +namespace Citrus\Collection; + +/** + * コレクションメソッド(判定系) + */ +class JudgeMentor +{ + /** + * 要素が空である + * + * @param array $source + * @param callable|null $callable function($value, $key) + * @return bool + */ + public static function isEmpty(array $source, callable|null $callable): bool + { + return Measurer::count($source, $callable) === 0; + } + + /** + * 要素が空ではない + * + * @param array $source + * @param callable|null $callable function($value, $key) + * @return bool + */ + public static function isNotEmpty(array $source, callable|null $callable): bool + { + return Measurer::count($source, $callable) !== 0; + } +} diff --git a/src/Collection/Measurer.php b/src/Collection/Measurer.php new file mode 100644 index 0000000..7d28a9d --- /dev/null +++ b/src/Collection/Measurer.php @@ -0,0 +1,34 @@ + + * @license http://www.citrus.tk/ + */ + +namespace Citrus\Collection; + +/** + * コレクションメソッド(計測系) + */ +class Measurer +{ + /** + * 要素数 + * + * @param array $source + * @param callable|null $callable function($value, $key) + * @return int + */ + public static function count(array $source, callable|null $callable): int + { + if (!is_null($callable)) + { + return count(Filter::filter($source, $callable)); + } + + return count($source); + } +} diff --git a/src/Collection/Register.php b/src/Collection/Register.php index a374c6d..019e392 100644 --- a/src/Collection/Register.php +++ b/src/Collection/Register.php @@ -18,11 +18,11 @@ class Register /** * callable関数がnull以外の値を返した場合、値を積んで返却する * - * @param iterable $source - * @param callable $callable function($key, $value) + * @param array $source + * @param callable $callable function($value, $key) * @return iterable */ - public static function append(iterable $source, callable $callable): iterable + public static function append(array $source, callable $callable): array { $results = []; foreach ($source as $ky => $vl) diff --git a/src/Collection/Scanner.php b/src/Collection/Scanner.php index fda47b2..680779b 100644 --- a/src/Collection/Scanner.php +++ b/src/Collection/Scanner.php @@ -18,11 +18,11 @@ class Scanner /** * callable関数を適用した内容を積んで返却する * - * @param iterable $source - * @param callable $callable function($key, $value) - * @return iterable + * @param array $source + * @param callable $callable function($value, $key) + * @return array */ - public static function map(iterable $source, callable $callable): iterable + public static function map(array $source, callable $callable): array { $results = []; foreach ($source as $ky => $vl) @@ -32,17 +32,15 @@ public static function map(iterable $source, callable $callable): iterable return $results; } - - /** * callable関数を適用した内容を積んで返却する * keyを指定する * - * @param iterable $source - * @param callable $callable function($key, $value) - * @return iterable + * @param array $source + * @param callable $callable function($value, $key) + * @return array */ - public static function mapWithKey(iterable $source, callable $callable): iterable + public static function mapWithKey(array $source, callable $callable): array { $results = []; foreach ($source as $ky => $vl) @@ -52,17 +50,15 @@ public static function mapWithKey(iterable $source, callable $callable): iterabl return $results; } - - /** * callable関数を適用した内容を積んで返却する * keyを維持する * - * @param iterable $source - * @param callable $callable function($key, $value) - * @return iterable + * @param array $source + * @param callable $callable function($value, $key) + * @return array */ - public static function keyMap(iterable $source, callable $callable): iterable + public static function keyMap(array $source, callable $callable): array { $results = []; foreach ($source as $ky => $vl) @@ -72,18 +68,15 @@ public static function keyMap(iterable $source, callable $callable): iterable return $results; } - - /** * 多次元コレクションを一次元にする * - * - * @param iterable $source + * @param array $source * @param int|null $depth 再起回数の指定 * @param bool $preserve_keys true:キーを維持する、キーが重複する場合は後勝ちする - * @return iterable + * @return array */ - public static function flatten(iterable $source, int $depth = null, bool $preserve_keys = false): iterable + public static function flatten(array $source, int $depth = null, bool $preserve_keys = false): array { $results = []; foreach ($source as $ky => $vl) diff --git a/src/Collection/Sorter.php b/src/Collection/Sorter.php index c91bf02..17d7aca 100644 --- a/src/Collection/Sorter.php +++ b/src/Collection/Sorter.php @@ -20,14 +20,13 @@ class Sorter * * callable関数は -1 or 0 or 1 を返却する * - * @param iterable|array $source - * @param callable $callable function($value1, $value2) - * @return iterable + * @param array $source + * @param callable $callable function($value1, $value2) + * @return array */ - public static function sortBy(iterable $source, callable $callable): iterable + public static function sortBy(array $source, callable $callable): array { - $results = (true === is_array($source) ? $source : iterator_to_array($source, true)); - usort($results, $callable); - return $results; + usort($source, $callable); + return $source; } } diff --git a/tests/CollectionTest.php b/tests/CollectionTest.php index a178249..1bb5a77 100644 --- a/tests/CollectionTest.php +++ b/tests/CollectionTest.php @@ -18,6 +18,14 @@ */ class CollectionTest extends TestCase { + /** @var array[] テスト配列 */ + private array $values = [ + ['name' => 'a', 'age' => 16], + ['name' => 'b', 'age' => 11], + ['name' => 'c', 'age' => 13], + ['name' => 'd', 'age' => 19], + ]; + /** * @test */ @@ -59,8 +67,6 @@ public function betterMerge_両方の要素を残したいい感じの配列マ $this->assertSame($expected, $actual); } - - /** * @test */ @@ -95,8 +101,6 @@ public function filter_指定データのみ残した配列生成() })->toList()); } - - /** * @test */ @@ -129,8 +133,6 @@ public function remove_指定データのみ削除した配列生成() })->toList()); } - - /** * @test */ @@ -152,8 +154,6 @@ public function notNull_nullデータを削除した配列生成() $this->assertSame($expected1, Collection::stream($values)->notNull()->toList()); } - - /** * @test */ @@ -175,8 +175,6 @@ public function where_指定した値が一致した場合取得() $this->assertSame($expected1, Collection::stream($values)->where('age', 12)->toValues()); } - - /** * @test */ @@ -205,8 +203,6 @@ public function append_データ生成できたものだけで配列生成() })->toList()); } - - /** * @test */ @@ -232,8 +228,6 @@ public function map_データ編集して配列生成() })->toList()); } - - /** * @test */ @@ -257,8 +251,6 @@ public function mapExecMethod_メソッド実行して配列生成() $this->assertEquals($expected, Collection::stream($values)->mapExecMethod('add')->toList()); } - - /** * @test */ @@ -284,8 +276,6 @@ public function mapWithKey_データ編集して配列生成() })->toList()); } - - /** * @test */ @@ -311,8 +301,6 @@ public function keyMap_データ編集して配列生成() })->toList()); } - - /** * @test */ @@ -361,8 +349,6 @@ public function chunk_データを分割して配列生成() $this->assertSame($expected, Collection::stream($values)->chunk(2, true)->toList()); } - - /** * @test */ @@ -445,8 +431,6 @@ public function flatten_多次元配列を一次元に変換して配列生成() $this->assertSame($expected, Collection::stream($values)->flatten(1, true)->toList()); } - - /** * @test */ @@ -470,8 +454,6 @@ public function range_指定範囲で配列生成() })->toList()); } - - /** * @test */ @@ -493,8 +475,6 @@ public function repeat_指定回数で配列生成() })->toList()); } - - /** * @test */ @@ -520,8 +500,6 @@ public function sortBy_ソートした配列を生成して返却() })->toList()); } - - /** * @test */ @@ -545,8 +523,6 @@ public function sortByProp_ソートした配列を生成して返却() $this->assertSame($expected, Collection::stream($values)->sortByProp('age', false)->toList()); } - - /** * @test */ @@ -573,24 +549,62 @@ public function sortByProps_ソートした配列を生成して返却() ])->toList()); } - - /** * @test */ public function one_一件だけ取得() { - $values = [ - ['name' => 'a', 'age' => 16], - ['name' => 'b', 'age' => 11], - ['name' => 'c', 'age' => 13], - ['name' => 'd', 'age' => 19], - ]; - // 降順にソート $expected = ['name' => 'a', 'age' => 16]; // 検算 - $this->assertSame($expected, Collection::stream($values)->one()); + $this->assertSame($expected, Collection::stream($this->values)->one()); + } + + /** + * @test + */ + public function count_件数取得() + { + // 検算 + $this->assertSame(4, Collection::stream($this->values)->count()); + // 検算:フィルター + $this->assertSame(2, Collection::stream($this->values)->count(function ($value, $key) { + return $value['age'] > 15; + })); + } + + /** + * @test + */ + public function isEmpty_要素が空である() + { + // 検算 + $this->assertSame(false, Collection::stream($this->values)->isEmpty()); + $this->assertSame(true, Collection::stream([])->isEmpty()); + // 検算:フィルター + $this->assertSame(false, Collection::stream($this->values)->isEmpty(function ($value, $key) { + return $value['age'] > 15; + })); + $this->assertSame(true, Collection::stream($this->values)->isEmpty(function ($value, $key) { + return $value['age'] > 19; + })); + } + + /** + * @test + */ + public function isNotEmpty_要素が空ではない() + { + // 検算 + $this->assertSame(true, Collection::stream($this->values)->isNotEmpty()); + $this->assertSame(false, Collection::stream([])->isNotEmpty()); + // 検算:フィルター + $this->assertSame(true, Collection::stream($this->values)->isNotEmpty(function ($value, $key) { + return $value['age'] > 15; + })); + $this->assertSame(false, Collection::stream($this->values)->isNotEmpty(function ($value, $key) { + return $value['age'] > 19; + })); } }