├── .github
└── workflows
│ ├── fasttest.yml
│ └── fulltest.yml
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── examples
├── readme-functional-libary.php
├── readme-functional-native.php
└── readme-structured.php
├── images
├── libary-functional-min.png
├── native-functional-min.png
└── structured-min.png
├── phpunit.xml
├── src
└── ArrayCreate.php
└── tests
├── ArrayCreateTest.php
├── ExamplesTest.php
└── WithoutComposerTest.php
/.github/workflows/fasttest.yml:
--------------------------------------------------------------------------------
1 | name: Fast Test Suite
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | phpunit:
7 | name: PHP ${{ matrix.php }} / No Composer
8 | runs-on: ubuntu-latest
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
13 |
14 | steps:
15 | - name: Checkout Project
16 | uses: actions/checkout@v2
17 |
18 | - name: Install PHP ${{ matrix.php }}
19 | uses: shivammathur/setup-php@v2
20 | with:
21 | php-version: ${{ matrix.php }}
22 | extensions: mbstring
23 | ini-values: date.timezone='UTC', session.save_path="${{ runner.temp }}"
24 |
25 | - name: PHP Unit tests for PHP ${{ matrix.php }}
26 | run: php ./tests/WithoutComposerTest.php
27 |
--------------------------------------------------------------------------------
/.github/workflows/fulltest.yml:
--------------------------------------------------------------------------------
1 | name: Full Test Suite
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | env:
12 | DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi"
13 | PHPUNIT_COVERAGE_FLAGS: "--coverage-clover=clover.xml"
14 | PHPUNIT_EXCLUDE_GROUP: "--exclude-group mssql,oci,wincache,xcache,zenddata,cubrid"
15 | XDEBUG_MODE: coverage, develop
16 |
17 | jobs:
18 | phpunit:
19 | name: PHP ${{ matrix.php }} / PHPUnit / Coverage / Composer
20 | runs-on: ubuntu-latest
21 | strategy:
22 | fail-fast: false
23 | matrix:
24 | php: ['7.4']
25 |
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v2
29 |
30 | - name: Install PHP
31 | uses: shivammathur/setup-php@v2
32 | with:
33 | php-version: ${{ matrix.php }}
34 | tools: pecl
35 | extensions: mbstring
36 | ini-values: date.timezone='UTC', session.save_path="${{ runner.temp }}"
37 |
38 | - name: Get composer cache directory
39 | id: composer-cache
40 | run: echo "::set-output name=dir::$(composer config cache-files-dir)"
41 |
42 | - name: Cache composer dependencies
43 | uses: actions/cache@v1
44 | with:
45 | path: ${{ steps.composer-cache.outputs.dir }}
46 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
47 | restore-keys: ${{ runner.os }}-composer-
48 |
49 | - name: Install dependencies
50 | run: composer update ${{ env.DEFAULT_COMPOSER_FLAGS }}
51 |
52 | - name: PHP Unit tests for PHP ${{ matrix.php }}
53 | run: vendor/bin/phpunit --verbose ${{ env.PHPUNIT_COVERAGE_FLAGS }} ${{ env.PHPUNIT_EXCLUDE_GROUP }} --colors=always
54 |
55 | - name: Report Coverage to Codacy
56 | if: github.event_name == 'push'
57 | run: bash <(curl -Ls https://coverage.codacy.com/get.sh) report --project-token ${{ secrets.CODACY_PROJECT_TOKEN }}
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | composer.phar
3 | ocular.phar
4 | /vendor/
5 | /.phpunit.cache/
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2022, RodrigoDornelles
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rodrigodornelles/php-array-lib
2 |
3 | [](https://packagist.org/packages/rodrigodornelles/php-array-lib)
4 | [](https://github.com/RodrigoDornelles/php-array-lib/blob/master/LICENSE)
5 | [](https://www.codacy.com/gh/RodrigoDornelles/php-array-lib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=RodrigoDornelles/php-array-lib&utm_campaign=Badge_Grade)
6 | [](https://www.codacy.com/gh/RodrigoDornelles/php-array-lib/dashboard?utm_source=github.com&utm_medium=referral&utm_content=RodrigoDornelles/php-array-lib&utm_campaign=Badge_Coverage)
7 | [](https://github.com/rodrigodornelles/php-array-lib/actions)
8 |
9 |
10 | > simple libary for functional programing paradigm with arrays
11 |
12 | ## Features ##
13 |
14 | * Test driven development style _(TDD)_
15 | * PHP version compatibility **5.4** at **8.2**
16 | * Make your code cleaner and more readable
17 | * Adds new methods to manipulate arrays _(Inspired by **ruby**, **js** and other langs)_
18 |
19 |
20 | ## How to Use
21 |
22 | ```PHP
23 |
24 | use ArrayCreate; # if you using namespaces
25 |
26 | $myNewArray = ArrayCreate::from($myOriginalArray) # instantiate pipeline class
27 | ->map(someItemFunction) # first function to iterate on each item
28 | ->map(anotherItemFunction) # next function to iterate on each item
29 | ->filter(anotherItemFunction2) # next function to filter on each item
30 | ->construct(); # returns new array
31 | ```
32 |
33 | ## Examples ##
34 |
35 | ### side by side comparison ###
36 |
37 | Make an algorithm that sorts an array, removes the numbers not divisible by 3, and shows the result of each multiplied by 2 and separated by commas.
38 |
39 | | Libary
Functional | Native
Functional | Structured |
40 | | :-: | :-: | :-: |
41 | | [](./examples/readme-functional-libary.php) | [](./examples/readme-functional-native.php) | [](./examples/readme-structured.php)
42 |
43 | ## Installation ##
44 |
45 | ### With Composer ###
46 |
47 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
48 |
49 | Either run
50 |
51 | ```SHELL
52 | $ composer require rodrigodornelles/php-array-lib "~1.0.0"
53 | ```
54 |
55 | or add
56 |
57 | ```JSON
58 | "rodrigodornelles/php-array-lib": "~1.0.0"
59 | ```
60 |
61 | to the `require` section of your `composer.json` file.
62 |
63 | ### Without Composer ###
64 |
65 | #### Step 1 ####
66 |
67 | Download libary in
68 |
69 | #### Step 2 ####
70 |
71 | Extract the file into your libraries folder
72 |
73 | #### Step 3 ####
74 |
75 | Import the main class
76 |
77 | ```PHP
78 | sort()
12 | ->filter(fn($n) => !($n % 3))
13 | ->map(fn($n) => $n * 2)
14 | ->join(', ');
15 | }
16 |
17 | readmeFunctionalLibary();
18 |
--------------------------------------------------------------------------------
/examples/readme-functional-native.php:
--------------------------------------------------------------------------------
1 | $n * 2,
11 | array_filter($numbers,
12 | fn($n) => !($n % 3)
13 | )
14 | )
15 | );
16 | }
17 |
18 | readmeFunctionalNative();
19 |
--------------------------------------------------------------------------------
/examples/readme-structured.php:
--------------------------------------------------------------------------------
1 | $number)
10 | {
11 | if ($number % 3) {
12 | continue;
13 | }
14 |
15 | echo $number * 2;
16 |
17 | if (array_key_last($numbers) !== $key) {
18 | echo ", ";
19 | }
20 | }
21 | }
22 |
23 | readmeStructured();
24 |
--------------------------------------------------------------------------------
/images/libary-functional-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RodrigoDornelles/php-array-lib/9d5e531ac2ec3db5c76e37181e512a2746d09898/images/libary-functional-min.png
--------------------------------------------------------------------------------
/images/native-functional-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RodrigoDornelles/php-array-lib/9d5e531ac2ec3db5c76e37181e512a2746d09898/images/native-functional-min.png
--------------------------------------------------------------------------------
/images/structured-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RodrigoDornelles/php-array-lib/9d5e531ac2ec3db5c76e37181e512a2746d09898/images/structured-min.png
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 | tests
18 |
19 |
20 |
21 |
23 |
24 | src
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/ArrayCreate.php:
--------------------------------------------------------------------------------
1 |
6 | * @copyright 2022, Rodrigo Dornelles
7 | *
8 | **
9 | *
10 | * @method construct
11 | * @method filter
12 | * @method first
13 | * @method flip
14 | * @method from
15 | * @method join
16 | * @method last
17 | * @method map
18 | * @method sort
19 | *
20 | **
21 | */
22 | class ArrayCreate
23 | {
24 | /**
25 | * Internal array
26 | *
27 | * @var array
28 | */
29 | private $_array;
30 |
31 | /**
32 | * @param array $params
33 | */
34 | private function __construct($params = [])
35 | {
36 | $this->_array = isset($params['from'])? (array) ($params['from']): [];
37 | }
38 |
39 | /**
40 | * @return array
41 | */
42 | public function construct()
43 | {
44 | return $this->_array;
45 | }
46 |
47 | /**
48 | * @param Closure $func
49 | *
50 | * @return ArrayCreate
51 | */
52 | public function filter($func)
53 | {
54 | $this->_array = array_filter($this->_array, $func);
55 | return $this;
56 | }
57 |
58 | /**
59 | * @return mixed
60 | */
61 | public function first()
62 | {
63 | $item = current(array_slice($this->_array, 0, 1));
64 | return is_array($item)? self::from($item): $item;
65 | }
66 |
67 | /**
68 | * @return ArrayCreate
69 | */
70 | public function flip()
71 | {
72 | $this->_array = array_flip($this->_array);
73 | return $this;
74 | }
75 |
76 | /**
77 | * @param array $array
78 | *
79 | * @return ArrayCreate
80 | */
81 | public static function from($array)
82 | {
83 | return new self(['from' => $array]);
84 | }
85 |
86 | /**
87 | * @param string $glue
88 | *
89 | * @return string
90 | */
91 | public function join($glue = '')
92 | {
93 | return implode($glue, $this->_array);
94 | }
95 |
96 | /**
97 | * @return mixed
98 | */
99 | public function last()
100 | {
101 | $item = end($this->_array);
102 | reset($this->_array);
103 | return is_array($item)? self::from($item): $item;
104 | }
105 |
106 | /**
107 | * @param Closure $func
108 | *
109 | * @return ArrayCreate
110 | */
111 | public function map($func)
112 | {
113 | $this->_array = array_map($func, $this->_array);
114 | return $this;
115 | }
116 |
117 | /**
118 | * @param Int $sort_flags
119 | *
120 | * @return ArrayCreate
121 | */
122 | public function sort($sort_flags = SORT_REGULAR)
123 | {
124 | sort($this->_array, $sort_flags);
125 | return $this;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/tests/ArrayCreateTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(ArrayCreate::class, $array);
15 | }
16 |
17 | public function testFilter()
18 | {
19 | $expected = [1, 3, 5, 7, 9];
20 | $expected = array_combine($expected, $expected);
21 | $actual = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
22 | $actual = ArrayCreate::from($actual)
23 | ->filter(function($n){return $n % 2;})
24 | ->construct();
25 |
26 | $this->assertSame($expected, $actual);
27 | }
28 |
29 | public function testFirst()
30 | {
31 | $expected = 'first';
32 | $actual = ['first', 'last'];
33 | $actual = ArrayCreate::from($actual)
34 | ->first();
35 |
36 | $this->assertSame($expected, $actual);
37 | }
38 |
39 | public function testFlip()
40 | {
41 | $expected = ['bar' => 'foo'];
42 | $actual = ['foo' => 'bar'];
43 | $actual = ArrayCreate::from($actual)
44 | ->flip()
45 | ->construct();
46 |
47 | $this->assertSame($expected, $actual);
48 | }
49 |
50 | public function testJoin()
51 | {
52 | $expected = 'foo, bar, z';
53 | $actual = ['foo', 'bar', 'z'];
54 | $actual = ArrayCreate::from($actual)
55 | ->join(', ');
56 |
57 | $this->assertSame($expected, $actual);
58 | }
59 |
60 | public function testLast()
61 | {
62 | $expected = 'last';
63 | $actual = ['first', 'last'];
64 | $actual = ArrayCreate::from($actual)
65 | ->last();
66 |
67 | $this->assertSame($expected, $actual);
68 | }
69 |
70 | public function testMap()
71 | {
72 | $expected = [2, 4, 6, 8];
73 | $actual = [1, 2, 3, 4];
74 | $actual = ArrayCreate::from($actual)
75 | ->map(function($n){return $n * 2;})
76 | ->construct();
77 |
78 | $this->assertSame($expected, $actual);
79 | }
80 | }
--------------------------------------------------------------------------------
/tests/ExamplesTest.php:
--------------------------------------------------------------------------------
1 | assertSame($expected, $content);
25 | }
26 |
27 | /**
28 | * @covers ::readmeFunctionalNative
29 | */
30 | public function testFunctionalNative()
31 | {
32 | $expected = '6, 30, 84, 108';
33 | ob_start();
34 | require __DIR__.'/../examples/readme-functional-native.php';
35 | $content = ob_get_contents();
36 | ob_end_clean();
37 |
38 | $this->assertSame($expected, $content);
39 | }
40 |
41 | /**
42 | * @covers ::readmeStructured
43 | */
44 | public function testReadmeStructured()
45 | {
46 | $expected = '6, 30, 84, 108';
47 | ob_start();
48 | require __DIR__.'/../examples/readme-structured.php';
49 | $content = ob_get_contents();
50 | ob_end_clean();
51 |
52 | $this->assertSame($expected, $content);
53 | }
54 | }
--------------------------------------------------------------------------------
/tests/WithoutComposerTest.php:
--------------------------------------------------------------------------------
1 | join(',') == 'FOO,BAR,Z');
11 |
12 | /** test 2 */
13 | $string = "0,1,2,3,5";
14 | $array = explode(",", $string);
15 | $array = ArrayCreate::from($array)->map(function($n) {return (int) $n;})->construct();
16 | assert(array_filter($array, 'is_int'));
17 |
18 | /** test 3 */
19 | $array = [1, 2, 3, 4, 5, 6, 7, 8, 9 ,10];
20 | $array = ArrayCreate::from($array)->filter(function($n) {return $n % 2;})->construct();
21 | assert(count($array) == 5);
22 |
23 | /** test 4 */
24 | $array = ['first', 'middle', 'last'];
25 | $array = ArrayCreate::from($array);
26 | assert($array->first() == 'first');
27 | assert($array->last() == 'last');
28 |
29 | /** test 5 */
30 | $array = ['first', 'middle', 'last'];
31 | $array = ArrayCreate::from($array)->flip()->construct();
32 | assert($array['first'] == 0);
33 | assert($array['last'] == 2);
34 |
35 | print("OK.\n");
36 |
--------------------------------------------------------------------------------