diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19982ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +composer.lock +vendor \ No newline at end of file diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..c3bb259 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1 @@ +preset: laravel \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7099431 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 7.2 + - 7.3 + +before_script: + - travis_retry composer install --no-interaction + +script: + - vendor/bin/phpunit --coverage-clover clover.xml + +after_script: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/README.md b/README.md index e60e12b..dd0f348 100644 --- a/README.md +++ b/README.md @@ -1 +1,33 @@ -# one-loop \ No newline at end of file +# One Loop + +[![Latest Version on Packagist](https://img.shields.io/packagist/v/hassan/one-loop.svg?style=flat-square)](https://packagist.org/packages/hassan/one-loop) +[![Build Status](https://badgen.net/travis/dhassanali/one-loop/master)](https://travis-ci.org/dhassanali/one-loop) +[![License](https://badgen.net/packagist/license/hassan/one-loop)](https://packagist.org/packages/hassan/one-loop) + +A Laravel/PHP Package for Minimizing Collection/Array Iterations + +## Installation + +Install the package via composer: + +```bash +composer require hassan/one-loop +``` + +## Usage + +``` php +$users = App\User::all(); + +$ids = one_loop($users)->reject(static function ($user) { + return $user->age < 20; +}) +->map(static function ($user) { + return $user->id; +}) +->apply(); +``` + +### Security + +If you discover any security related issues, please email hello@hassan-ali.me instead of using the issue tracker. \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..a646c28 --- /dev/null +++ b/composer.json @@ -0,0 +1,47 @@ +{ + "name": "hassan/one-loop", + "description": "A Laravel/PHP Package for Minimizing Collection/Array Iterations", + "keywords": [ + "hassan", + "one-loop", + "collect", + "collection", + "laravel-collection" + ], + "homepage": "https://github.com/dhassanali/one-loop", + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Hassan Ali", + "email": "hello@hassan-ali.me" + } + ], + "require": { + "php": "^7.1", + "illuminate/support": "5.8.*", + "illuminate/contracts": "5.8.*" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Hassan\\OneLoop\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Hassan\\OneLoop\\Tests\\": "tests" + } + }, + "scripts": { + "test": "vendor/bin/phpunit" + }, + "config": { + "sort-packages": true + } +} \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..6571e91 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + + tests + + + + + src/ + + + \ No newline at end of file diff --git a/src/OneLoop.php b/src/OneLoop.php new file mode 100644 index 0000000..b283e1d --- /dev/null +++ b/src/OneLoop.php @@ -0,0 +1,78 @@ +items = $this->getArrayableItems($items); + } + + public function apply() : array + { + foreach ($this->items as $key => $item) { + $this->applyMethods($item, $key); + } + + return $this->items; + } + + private function applyMethods($item, $index) : void + { + foreach ($this->applicableMethods as $key => $method) { + + if (!isset($this->items[$index])) { + continue; + } + + switch ($key) { + case 'map': + $this->items[$index] = $method($item, $index); + break; + + case 'reject': + if ((bool) $method($item, $index)) { + unset($this->items[$index]); + } + break; + } + } + } + + protected function getArrayableItems($items) + { + if (is_array($items)) { + return $items; + } + + if ($items instanceof Collection) { + return $items->all(); + } + + return (array) $items; + } + + public function __call($name, $arguments) + { + if ( + isset($arguments[0]) && + in_array($name, static::$availableMethods, true) && + is_callable($arguments[0]) + ) { + $this->applicableMethods[$name] = $arguments[0]; + + return $this; + } + + return $this->$name(...$arguments); + } +} \ No newline at end of file diff --git a/src/helpers.php b/src/helpers.php new file mode 100644 index 0000000..e67ab93 --- /dev/null +++ b/src/helpers.php @@ -0,0 +1,12 @@ +getUsers()); + + $ids = one_loop($users) + ->reject(static function ($user) { + return $user->age < 20; + })->map(static function ($user) { + return $user->id; + })->apply(); + + $this->assertCount(2, $ids); + } + + private function getUsers() + { + $user1 = new \stdClass(); + $user1->id = 1; + $user1->age = 32; + + $user2 = new \stdClass(); + $user2->id = 2; + $user2->age = 2; + + $user3 = new \stdClass(); + $user3->id = 3; + $user3->age = 42; + + return [$user1, $user2, $user3]; + } + + public function test_numbers() + { + $numbers = one_loop([1, 2, 3]) + ->reject(static function ($item) { + return $item === 2; + })->map(static function ($item) { + return $item * 3; + })->apply(); + + $this->assertCount(2, $numbers); + } +} \ No newline at end of file