diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ec68ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/vendor/ +composer.lock +coverage.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..43f7b46 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +tester = vendor/bin/tester +tests_dir = tests/ +coverage_name = $(tests_dir)coverage.html +php_ini = $(tests_dir)php-unix.ini +php_bin = php + +.PHONY: test coverage clean +test: + @$(tester) -p $(php_bin) -c $(php_ini) $(tests_dir) + +coverage: + @$(tester) -p $(php_bin) -c $(php_ini) --coverage $(coverage_name) --coverage-src src/ $(tests_dir) + +clean: + @rm -f $(coverage_name) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..97cd6e1 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "czproject/arrays", + "type": "library", + "description": "Array tools library.", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Jan Pecha", + "homepage": "https://www.janpecha.cz/" + } + ], + "require": { + "php": ">=5.4.0" + }, + "autoload": { + "classmap": ["src/"] + }, + "require-dev": { + "nette/tester": "^1.7" + } +} diff --git a/license.md b/license.md new file mode 100644 index 0000000..4c52135 --- /dev/null +++ b/license.md @@ -0,0 +1,26 @@ +New BSD License +--------------- + +Copyright © 2016 Jan Pecha (https://www.janpecha.cz/) All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. +* Neither the name of “CzProject“ nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..fad9d7d --- /dev/null +++ b/readme.md @@ -0,0 +1,148 @@ + +# CzProject\Arrays + +Array tools library. + +## Usage + + +``` php + array( + 'value 2-1', + 'value 2-2', + 'value 2-3', + ), + 'value 3', +)); + +/* Returns: +[ + 'value 1', + 'value 2-1', + 'value 2-2', + 'value 2-3', + 'value 3', +] +*/ +``` + + +### `fetchPairs()` + +``` php + 1, + 'name' => 'Row #1', + ), + + array( + 'id' => 2, + 'name' => 'Row #2', + ), + + array( + 'id' => 3, + 'name' => 'Row #3', + ), +); + +$data = Arrays::fetchPairs($rows, 'id', 'name'); + +/* Returns: +[ + 1 => 'Row #1', + 2 => 'Row #2', + 3 => 'Row #3', +] +*/ +``` + + +### `merge()` + +``` php + array( + 'database' => array( + 'host' => 'localhost', + 'database' => 'lorem_ipsum', + 'driver' => 'mysql', + ), + ), + + 'messages' => array( + 'success' => 'Success!', + 'error' => 'Error!', + ), +); + +$config = array( + 'parameters' => array( + 'database' => array( + 'user' => 'user123', + 'password' => 'password123', + ), + ), + + 'messages' => array( + 'error' => 'Fatal Error!', + ), +); + +$data = Arrays::merge($config, $defaultConfig); + +/* Returns: +[ + parameters => [ + database => [ + host => 'localhost', + database => 'lorem_ipsum', + driver => 'mysql', + user => 'user123', + password => 'password123', + ] + ], + + messages => [ + success => 'Success!', + error => 'Fatal Error!', + ] +] +*/ +``` + + +Installation +------------ + +[Download a latest package](https://github.com/czproject/arrays/releases) or use [Composer](http://getcomposer.org/): + +``` +composer require [--dev] czproject/arrays +``` + +`CzProject\Arrays` requires PHP 5.4.0 or later. + + +------------------------------ + +License: [New BSD License](license.md) +
Author: Jan Pecha, https://www.janpecha.cz/ diff --git a/src/Arrays.php b/src/Arrays.php new file mode 100644 index 0000000..251c823 --- /dev/null +++ b/src/Arrays.php @@ -0,0 +1,109 @@ + $value) { + if (is_array($value) || $value instanceof \Traversable) { + static::recursiveWalk($value, $callback); + + } else { + call_user_func_array($callback, array($value, $key)); + // $callback($value, $key); + } + } + } + + + /** + * @param array|object[] + * @param string|callback + * @param string|callback + * @return array + */ + public static function fetchPairs($data, $key, $value) + { + $list = array(); + + foreach ($data as $row) { + $itemKey = NULL; + $itemLabel = NULL; + + if (is_callable($key)) { + $itemKey = call_user_func_array($key, array($row)); + + } else { + $itemKey = is_array($row) ? $row[$key] : $row->{$key}; + } + + if (is_callable($value)) { + $itemLabel = call_user_func_array($value, array($row)); + + } else { + $itemLabel = is_array($row) ? $row[$value] : $row->{$value}; + } + + $list[$itemKey] = $itemLabel; + } + + return $list; + } + + + /** + * Merges arrays. Left has higher priority than right one. + * @param array|NULL + * @param array|NULL + * @return array|string + * @see https://github.com/nette/di/blob/master/src/DI/Config/Helpers.php + */ + public static function merge($left, $right) + { + if (is_array($left) && is_array($right)) { + foreach ($left as $key => $val) { + if (is_int($key)) { + $right[] = $val; + + } else { + if (isset($right[$key])) { + $val = static::merge($val, $right[$key]); + } + $right[$key] = $val; + } + } + return $right; + + } elseif ($left === NULL && is_array($right)) { + return $right; + + } else { + return $left; + } + } + } diff --git a/tests/Arrays/fetchPairs.phpt b/tests/Arrays/fetchPairs.phpt new file mode 100644 index 0000000..fcf00b1 --- /dev/null +++ b/tests/Arrays/fetchPairs.phpt @@ -0,0 +1,71 @@ + 1, + 'name' => 'Row #1', + ), + + array( + 'id' => 2, + 'name' => 'Row #2', + ), + + array( + 'id' => 3, + 'name' => 'Row #3', + ), + ); + + $data = Arrays::fetchPairs($rows, 'id', 'name'); + + Assert::same(array( + 1 => 'Row #1', + 2 => 'Row #2', + 3 => 'Row #3', + ), $data); + +}); + + +test(function () { + + $rows = array( + array( + 'id' => 1, + 'name' => 'Row #1', + ), + + array( + 'id' => 2, + 'name' => 'Row #2', + ), + + array( + 'id' => 3, + 'name' => 'Row #3', + ), + ); + + $data = Arrays::fetchPairs($rows, function ($row) { + return $row['id'] + 10; + + }, function ($row) { + return strtoupper($row['name']); + }); + + Assert::same(array( + 11 => 'ROW #1', + 12 => 'ROW #2', + 13 => 'ROW #3', + ), $data); + +}); diff --git a/tests/Arrays/flatten.phpt b/tests/Arrays/flatten.phpt new file mode 100644 index 0000000..4828ea4 --- /dev/null +++ b/tests/Arrays/flatten.phpt @@ -0,0 +1,27 @@ + array( + 'value 2-1', + 'value 2-2', + 'value 2-3', + ), + 'value 3', + ))); + +}); diff --git a/tests/Arrays/merge.phpt b/tests/Arrays/merge.phpt new file mode 100644 index 0000000..acb3c57 --- /dev/null +++ b/tests/Arrays/merge.phpt @@ -0,0 +1,116 @@ + array( + 'database' => array( + 'host' => 'localhost', + 'database' => 'lorem_ipsum', + 'driver' => 'mysql', + ), + ), + + 'messages' => array( + 'success' => 'Success!', + 'error' => 'Error!', + ), + ); + + $config = array( + 'parameters' => array( + 'database' => array( + 'user' => 'user123', + 'password' => 'password123', + ), + ), + + 'messages' => array( + 'error' => 'Fatal Error!', + ), + ); + + $data = Arrays::merge($config, $defaultConfig); + + Assert::same(array( + 'parameters' => array( + 'database' => array( + 'host' => 'localhost', + 'database' => 'lorem_ipsum', + 'driver' => 'mysql', + 'user' => 'user123', + 'password' => 'password123', + ), + ), + + 'messages' => array( + 'success' => 'Success!', + 'error' => 'Fatal Error!', + ) + ), $data); + +}); + + +test(function () { + + $data = array( + 'parameters' => array( + 'host' => 'localhost', + ), + ); + + Assert::same($data, Arrays::merge(NULL, $data)); + +}); + + +test(function () { + + $data = array( + 'parameters' => array( + 'host' => 'localhost', + ), + ); + + Assert::same($data, Arrays::merge($data, NULL)); + +}); + + +test(function () { + + $default = array( + 'parameters' => array( + 'host' => 'localhost', + ), + 'ignore' => array( + '.git*', + '/vendor/', + ), + ); + + $config = array( + 'ignore' => array( + '*.txt', + ), + ); + + Assert::same(array( + 'parameters' => array( + 'host' => 'localhost', + ), + 'ignore' => array( + '.git*', + '/vendor/', + '*.txt', + ), + ), Arrays::merge($config, $default)); + +}); diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..893e8d2 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,11 @@ +