diff --git a/Helpers/helpers.php b/Helpers/helpers.php index 71e7688..be98c81 100644 --- a/Helpers/helpers.php +++ b/Helpers/helpers.php @@ -14,4 +14,36 @@ function arrayed(...$value) { return new Arrayed(...$value); } +} + +if (! function_exists('configured')) { + /** + * Get config value + * + *
Up to firs level without Laravel config + * + * @param $value + * @param null $default + * @return mixed + */ + function configured($value, $default = null) + { + if (function_exists('config')) { + return config($value, $default); + } + + $keys = explode('.', $value); + + $data = require (__DIR__.'/../config/'.$keys[0].'.php'); + + foreach ($keys as $index => $key) { + if ($index < 1) { + continue; + } + + return $data[$key] ?? $default; + } + + return $data; + } } \ No newline at end of file diff --git a/README.md b/README.md index dcc6594..82a08bf 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,11 @@ Minimum Requirement ```php arrayed(1, 2, 'ninja') - ->filter(fn($val) => is_int($val)) - ->map(fn($val) => $val + 1) - ->flip() - ->values() - ->sum()(); //use () or ->result() at the end; + ->filter(fn($val) => is_int($val)) // [1,2] + ->map(fn($val) => $val + 1) // [2, 3] + ->flip() // [0, 1] + ->values() // [0, 1] + ->sum(); // 1 ``` Instead of: @@ -85,6 +85,16 @@ arrayed(['a' => 1, 'b' => 2]); Laravel Collections +New: `collect()` method :tada: + +```php +arrayed(1,2)->collect(); // instance of Illuminate/Support/Collection +arrayed(1,2)->collect(3, 4); //merged with first one to give [1, 2, 3, 4] +``` +> Swap out the default Collection class by editing `config/arrayed.php`'s collection_class value + +Others: + ```php collect(arrayed(1, 2, 3, 4)); @@ -101,6 +111,17 @@ Laravel Response accepts `Arrayed`: response()->json(arrayed(1, 2, 3)->flip()); ``` +#### Special methods + +New :tada: `tap()` method allows other actions on the last resulting `Arrayed` instance without mutating the last `Arrayed` result: + +```php +arrayed(1, 2, 3) + ->tap(function ($arrd) { + logger('Array has '.$arrd->count()); + }); +``` + ## Others If any operation normally returns an array, the return value will give `Arrayed` instance so that other methods can be chained on them otherwise a non-array value is returned as can be seen that `sum()` returns an integer in the example below: @@ -113,7 +134,7 @@ arrayed(['a' => 1, 'b' => 2]) ->sum(); // returns an integer, we cannot chain ``` -You can still work on the result (if its an array'ed value) by passing a closure/callable function to `result()` method: +You can work on a result (if its an array'ed value) by passing a closure/callable function to `result()` method: ```php arrayed(['a' => 'name', 'b' => 'age']) @@ -132,6 +153,7 @@ Get the original array data with `raw()` method arrayed([1, 2])->raw(); //[1,2] ``` +#### Piped calls As at now not all `array_*` functions have been implemented. `pipe()` method helps to call custom function on the array result. @@ -166,10 +188,10 @@ arrayed(['a', 'b']) ## APIs -These are the API's available +These are the API's available: ```php -static Arrayed::on(...$values): ArrayedInterface; +static Arrayed::on(...$values): ArrayedInterface; //new instance of Arrayed Arrayed::map($callback): ArrayedInterface; @@ -217,7 +239,29 @@ Arrayed::raw(): array; Arrayed::initial(): array; // Deprecated, use raw() instead -Arrayed::__toString(): string; // returns string rep of the array +Arrayed::tap(Closure $closure): ArrayedInterface; + +Arrayed::copy(): ArrayedInterface; + +Arrayed::collect(...$with): array; + +// Other Array_* methods + +Arrayed::changeKeyCase(int $case = null): ArrayedInterface; + +Arrayed::chunk(int $size, bool $preserve_keys = false): ArrayedInterface; + +Arrayed::column($column, $index_key = null): ArrayedInterface; + +Arrayed::countValues(): ArrayedInterface; + +Arrayed::diffAssoc(array $array2, array ...$_): ArrayedInterface; + +Arrayed::diff(array $array2, array ...$_): ArrayedInterface; + +Arrayed::reverse(bool $preserve_keys = false): ArrayedInterface; + + ``` ## Additional Information diff --git a/composer.json b/composer.json index b6f814b..52ec921 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,8 @@ }, "require-dev": { "phpunit/phpunit": ">=8.0", - "squizlabs/php_codesniffer": "3.*" + "squizlabs/php_codesniffer": "3.*", + "illuminate/support": ">=5.5" }, "autoload": { "psr-4": { diff --git a/config/arrayed.php b/config/arrayed.php new file mode 100644 index 0000000..d66938a --- /dev/null +++ b/config/arrayed.php @@ -0,0 +1,6 @@ + '\\Illuminate\\Support\\Collection', +]; \ No newline at end of file diff --git a/src/Arrayed.php b/src/Arrayed.php index 4f16caf..06d7d09 100644 --- a/src/Arrayed.php +++ b/src/Arrayed.php @@ -2,9 +2,11 @@ namespace Transprime\Arrayed; +use Closure; use ArrayIterator; -use Transprime\Arrayed\Traits\ArrayPrefix; +use Transprime\Arrayed\Exceptions\ArrayedException; use Transprime\Arrayed\Types\Undefined; +use Transprime\Arrayed\Traits\ArrayPrefix; use Transprime\Arrayed\Interfaces\ArrayedInterface; class Arrayed implements ArrayedInterface @@ -215,6 +217,34 @@ public function jsonSerialize() public function copy(): ArrayedInterface { - return new self($this->result()); + return new static($this->result()); + } + + public function tap(Closure $closure): ArrayedInterface + { + function_exists('tap') ? tap($this->copy(), $closure) : $closure($this->copy()); + + return $this; + } + + /** + * @param $with + * @return mixed + * @throws ArrayedException + */ + public function collect(...$with) + { + $collectionClass = $this->getConfig('collection_class'); + + if ($collectionClass && class_exists($collectionClass)) { + return new $collectionClass($this->copy()->merge($with)->result()); + } + + throw new ArrayedException('Collection class is not set or does not exist'); + } + + private function getConfig($item) + { + return configured("arrayed.$item", null); } } diff --git a/src/Interfaces/ArrayedInterface.php b/src/Interfaces/ArrayedInterface.php index 4d28db7..7dc9a6a 100644 --- a/src/Interfaces/ArrayedInterface.php +++ b/src/Interfaces/ArrayedInterface.php @@ -2,10 +2,12 @@ namespace Transprime\Arrayed\Interfaces; +use Closure; use Countable; use ArrayAccess; use JsonSerializable; use IteratorAggregate; +use Transprime\Arrayed\Exceptions\ArrayedException; interface ArrayedInterface extends ArrayAccess, Countable, IteratorAggregate, JsonSerializable { @@ -60,10 +62,16 @@ public function raw(): array; */ public function initial(): array; - public function __toString(): string; - public function copy(): ArrayedInterface; + public function tap(Closure $closure): ArrayedInterface; + + /** + * @param $with + * @return \Illuminate\Support\Collection|mixed + */ + public function collect(...$with); + public function changeKeyCase(int $case = null): ArrayedInterface; diff --git a/tests/ArrayedTest.php b/tests/ArrayedTest.php index b4b6514..2840523 100644 --- a/tests/ArrayedTest.php +++ b/tests/ArrayedTest.php @@ -338,4 +338,30 @@ public function testCopy() $this->assertEquals($arrayed, $arrayed->copy()); $this->assertNotSame($arrayed, $arrayed->copy()); } + + public function testTap() + { + $res = []; + $arrayed = arrayed(1, 2, 3) + ->tap(function ($arrd) use (&$res) { + $res = $arrd->reverse(); + }); + + $this->assertEquals($arrayed[0], $res[2]); + } + + public function testCollect() + { + $this->assertIsObject( + arrayed(1, 2, 3) + ->collect() + ); + + $this->assertEquals( + 6, + arrayed(1, 2, 3) + ->collect(2, 3, 4) + ->count() + ); + } }