first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-06-08 17:09:23 -04:00
commit df3a033196
17887 changed files with 8637778 additions and 0 deletions
@@ -0,0 +1,53 @@
filter:
excluded_paths:
- 'tests/*'
checks:
php:
more_specific_types_in_doc_comments: true
naming_conventions:
local_variable: '^[a-z][a-zA-Z0-9]*$'
abstract_class_name: ^Abstract|Factory$
utility_class_name: '.*'
constant_name: '^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$'
property_name: '^[a-z][a-zA-Z0-9]*$'
method_name: '^(?:[a-z]|__)[a-zA-Z0-9]*$'
parameter_name: '^[a-z][a-zA-Z0-9]*$'
interface_name: '^[A-Z][a-zA-Z0-9]*Interface$'
type_name: '^[A-Z][a-zA-Z0-9]*$'
exception_name: '^[A-Z][a-zA-Z0-9]*Exception$'
isser_method_name: '^(?:is|has|should|may|supports)'
overriding_parameter: true
param_doc_comment_if_not_inferrable: true
parameter_doc_comments: true
parameters_in_camelcaps: true
properties_in_camelcaps: true
return_doc_comment_if_not_inferrable: true
return_doc_comments: true
check_method_contracts:
verify_interface_like_constraints: true
verify_documented_constraints: true
verify_parent_constraints: true
coding_style:
php:
indentation:
general:
size: 1
spaces:
around_operators:
bitwise: false
build:
tests:
override:
- command: 'mkdir -p build/logs'
- command: 'php vendor/bin/phpunit --coverage-clover=build/logs/clover.xml'
coverage:
file: 'build/logs/clover.xml'
format: 'clover'
nodes:
tests: true
analysis:
tests:
override:
- command: phpcs-run
use_website_config: true
- php-scrutinizer-run
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Sebastian Böttger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,398 @@
[![PHP](https://img.shields.io/badge/PHP-%3E=7.1-green.svg?style=flat)](http://docs.php.net/manual/en/migration71.new-features.php)
[![Total Downloads](https://poser.pugx.org/seboettg/collection/downloads)](https://packagist.org/packages/seboettg/collection/stats)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/seboettg/Collection/blob/master/LICENSE)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/seboettg/Collection/badges/quality-score.png?b=version-2.0)](https://scrutinizer-ci.com/g/seboettg/Collection/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/seboettg/Collection/badges/build.png?b=master)](https://scrutinizer-ci.com/g/seboettg/Collection/build-status/master)
[![Code Coverage](https://scrutinizer-ci.com/g/seboettg/Collection/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/seboettg/Collection/code-structure/master)
[![Code Intelligence Status](https://scrutinizer-ci.com/g/seboettg/Collection/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence)
# Collection
Collection is a set of useful wrapper classes for arrays, similar to Java Collection.
## Versions
Since [Version 2.1](https://github.com/seboettg/Collection/releases/tag/v2.1.0) you need PHP 7.1 to use Collection library. Previous versions are running from PHP 5.6 upwards.
### ArrayList, Stack, Queue ###
The current version comes with a [ArrayList](#arraylist), a [Stack](#stack), and a [Queue](#queue). These classes can be used as wrapper instead using simple arrays. This approach guarantees consistently object-oriented handling for collection-like data-structures.
### Advantages of ArrayList ###
ArrayList is powerful alternative with a lot of of features:
* Sorting: You may implement the Comparable interface for elements of the ArrayList and the abstract class Comparator to be able to [sort the Elements in the ArrayList](#sorting-an-arraylist) comfortable.
* Filter: Apply a [filter](#filter-your-list) function or filter by keys.
* Map: [Apply a function on each list item](#apply-a-function-on-each-element).
### Easy and versatile to integrate ###
* Use inheritance to take advantages of the classes, or
* Use the interfaces and the belonging traits, if you already inherit another class
Take also a look to the UML [class diagram](#class-diagram).
# Installing Collection ##
The recommended way to install Collection is through
[Composer](http://getcomposer.org).
```bash
# Install Composer
curl -sS https://getcomposer.org/installer | php
```
Next, run the Composer command to install the latest stable version of Collection:
```bash
php composer.phar require seboettg/collection
```
After installing, you need to require Composer's autoloader:
```php
require 'vendor/autoload.php';
```
You can then later update Collection using composer:
```bash
composer.phar update
```
## ArrayList ##
### Simple Usage ###
Initialize ArrayList
```php
<?php
use Seboettg\Collection\ArrayList;
$list = new ArrayList("a", "c", "h", "k", "j");
$map = new ArrayList();
$map->setArray([
"c" => "cc",
"b" => "bb",
"a" => "aa"
]);
```
Get elements
```php
for ($i = 0; $i < $list->count(); ++$i) {
echo $list->get($i)." ";
}
```
This will output:
```bash
a c h k j
```
ArrayList implements the ArrayAccess interface, so you can also access elements in an instance of ArrayList in exactly the same way as you access an element in arrays:
```php
for ($i = 0; $i < $list->count(); ++$i) {
echo $list[$i]." ";
}
```
Iterate ArrayList using foreach
```php
foreach ($map as $key => $value) {
echo "[".$key."] => ".$value."\n";
}
```
Output:
```bash
c => cc
b => bb
a => aa
```
Set, add or append Elements
```php
//set element
$map->set("d", "dd");
//or
$map["d"] = "dd";
//add element
$map->add("d", "ddd")
print_r($map[$d]);
/*
output:
Array(
0 => "dd",
1 => "ddd"
)
*/
$list->append("z"); //append to the end of $list
```
remove, replace, clear
```php
$map->remove("d"); //removes d from $map
$list->replace(["z", "y", "x"]); //replaces all elements by the specified
$list->clear(); //removes all elements of the list
```
### Advanced Usage ###
#### Inherit from ArrayList ####
Inherit from ArrayList to extend your class with the whole functionality from ArrayList:
```php
<?php
namespace Vendor\Project;
use Seboettg\Collection\ArrayList;
class MyCustomList extends ArrayList {
protected $myCustomProperty;
protected function myCustomFunction()
{
//...
}
}
```
Or implement ArrayListInterface and use the ArrayListTrait (which implements all functions that are required by the interface) in case of that your custom class inherits already from another class
```php
<?php
namespace Vendor\Project;
use Seboettg\Collection\ArrayList\ArrayListInterface;
use Seboettg\Collection\ArrayList\ArrayListTrait;
class MyCustomList extends MyOtherCustomClass implements ArrayListInterface {
use ArrayListTrait;
protected $myCustomProperty;
protected function myCustomFunction()
{
//...
}
}
```
#### Sorting an ArrayList ####
Implement the Comparable interface
```php
<?php
namespace Vendor\App\Model;
use Seboettg\Collection\Comparable\Comparable;
class Element implements Comparable
{
private $attribute1;
private $attribute2;
//contructor
public function __construct($attribute1, $attribute2)
{
$this->attribute1 = $attribute1;
$this->attribute2 = $attribute2;
}
// getter
public function getAttribute1() { return $this->attribute1; }
public function getAttribute2() { return $this->attribute2; }
//compareTo function
public function compareTo(Comparable $b): int
{
return strcmp($this->attribute1, $b->getAttribute1());
}
}
```
Create a comparator class
```php
<?php
namespace Vendor\App\Util;
use Seboettg\Collection\Comparable\Comparator;
use Seboettg\Collection\Comparable\Comparable;
class Attribute1Comparator extends Comparator
{
public function compare(Comparable $a, Comparable $b): int
{
if ($this->sortingOrder === Comparator::ORDER_ASC) {
return $a->compareTo($b);
}
return $b->compareTo($a);
}
}
```
Sort your list
```php
<?php
use Seboettg\Collection\ArrayList;
use Seboettg\Collection\Collections;
use Seboettg\Collection\Comparable\Comparator;
use Vendor\App\Util\Attribute1Comparator;
use Vendor\App\Model\Element;
$list = new ArrayList(
new Element("b","bar"),
new Element("a","foo"),
new Element("c","foobar")
);
Collections::sort($list, new Attribute1Comparator(Comparator::ORDER_ASC));
```
#### sort your list using a custom order ####
```php
<?php
use Seboettg\Collection\Comparable\Comparator;
use Seboettg\Collection\Comparable\Comparable;
use Seboettg\Collection\ArrayList;
use Seboettg\Collection\Collections;
use Vendor\App\Model\Element;
//Define a custom Comparator
class MyCustomOrderComparator extends Comparator
{
public function compare(Comparable $a, Comparable $b): int
{
return (array_search($a->getAttribute1(), $this->customOrder) >= array_search($b->getAttribute1(), $this->customOrder)) ? 1 : -1;
}
}
$list = new ArrayList(
new Element("a", "aa"),
new Element("b", "bb"),
new Element("c", "cc"),
new Element("k", "kk"),
new Element("d", "dd"),
);
Collections::sort(
$list, new MyCustomOrderComparator(Comparator::ORDER_CUSTOM, ["d", "k", "a", "b", "c"])
);
```
#### filter your list ####
```php
$list = new ArrayList(
new Element("a", "aa"),
new Element("b", "bb"),
new Element("c", "cc"),
new Element("k", "kk"),
new Element("d", "dd"),
);
$newList = $list->filterByKeys([0, 2]); //returns new list containing 1st and 3rd element of $list
```
#### custom filter ####
```php
$list = new ArrayList(
new Element("a", "aa"),
new Element("b", "bb"),
new Element("c", "cc"),
new Element("k", "kk"),
new Element("d", "dd"),
);
$arrayList = $list->filter(function (Element $elem) {
return $elem->getAttribute2() === 'bb' || $elem->getAttribute2() === 'kk';
});
// $arrayList contains just the 2nd and the 4th element of $list
```
#### apply a function on each element ####
```php
$list = new ArrayList(1, 2, 3, 4, 5);
$cubicList = $list->map(function($i) {
return $i * $i * $i;
});
// cubicList looks like this now: [1, 8, 27, 64, 125]
```
## Stack ##
A stack is a collection of elements, with two principal operations:
* push, which adds an element to the collection, and
* pop, which removes the most recently added element that was not yet removed.
An Stack is a LIFO data structure: last in, first out.
### Examples ###
#### push, pop and peek ####
```php
$stack = new Stack();
$stack->push("a")
->push("b")
->push("c");
echo $stack->pop(); // outputs c
echo $stack->count(); // outputs 2
// peek returns the element at the top of this stack without removing it from the stack.
echo $stack->peek(); // outputs b
echo $stack->count(); // outputs 2
```
#### search ####
The search function returns the position where an element is on this stack. If the passed element occurs as an element
in this stack, this method returns the distance from the top of the stack of the occurrence nearest the top of the
stack; the topmost element on the stack is considered to be at distance 1. If the passed element does not occur in
the stack, this method returns 0.
```php
echo $stack->search("c"); //outputs 0 since c does not exist anymore
echo $stack->search("a"); //outputs 2
echo $stack->search("b"); //outputs 1
```
## Queue ##
A queue is a collection in which the elements are kept in order. A queue has two principle operations:
* enqueue
* dequeue
### Examples ###
```php
$queue = new Queue();
$queue->enqueue("d")
->enqueue("z")
->enqueue("b")
->enqueue("a");
echo $queue->dequeue(); // outputs d
echo $queue->dequeue(); // outputs z
echo $queue->dequeue(); // outputs b
echo $queue->count(); // outputs 1
```
## Class diagram ##
![class diagram](https://github.com/seboettg/collection/raw/master/class-diagram.png "class diagram")
## Contribution ##
Fork this Repo and feel free to contribute your ideas using pull requests.
@@ -0,0 +1,3 @@
<?php
require 'vendor/autoload.php';
Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

@@ -0,0 +1,43 @@
{
"name": "seboettg/collection",
"description": "Collection is a set of useful PHP wrapper classes for arrays, similar to Java Collection. Contains ArrayList, Stack, Queue.",
"license": "MIT",
"keywords": [
"arraylist",
"sort",
"collections",
"comparable",
"array",
"oop",
"datastructures",
"basic-data-structures",
"stack",
"queue",
"comparator",
"filter",
"map",
"comparable-interface"
],
"authors": [
{
"name": "Sebastian Böttger",
"email": "seboettg@gmail.com"
}
],
"autoload": {
"psr-4": {"Seboettg\\Collection\\": "src/"},
"files": [
"src/ArrayList/Functions.php"
]
},
"autoload-dev": {
"psr-4": {"Seboettg\\Collection\\Test\\": "tests/"}
},
"require": {
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "8.5.*",
"php-coveralls/php-coveralls": "^1"
}
}
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="bootstrap.php">
<php>
<!-- -->
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src</directory>
<exclude>
<directory>./vendor</directory>
<directory>./tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection;
use Seboettg\Collection\ArrayList\ArrayListInterface;
use Seboettg\Collection\ArrayList\ArrayListTrait;
/**
* ArrayList is a useful wrapper class for an array, similar to Java's ArrayList
* @package Seboettg\Collection
*
* @author Sebastian Böttger <seboettg@gmail.com>
*/
class ArrayList implements ArrayListInterface
{
use ArrayListTrait;
/**
* @var array
*/
protected $array;
/**
* ArrayList constructor.
* @param array $data
*/
public function __construct(...$data)
{
$this->array = $data;
}
}
@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\ArrayList;
use ArrayIterator;
/**
* Trait ArrayAccessTrait
* @package Seboettg\Collection\ArrayList
* @property $array Base array of this data structure
*/
trait ArrayAccessTrait
{
/**
* {@inheritDoc}
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->array);
}
/**
* Offset to retrieve
* @link http://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset The offset to retrieve.
*
* @return mixed Can return all value types.
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return isset($this->array[$offset]) ? $this->array[$offset] : null;
}
/**
* Offset to set
* @link http://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset The offset to assign the value to.
* @param mixed $value The value to set.
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->array[$offset] = $value;
}
/**
* Whether a offset exists
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
*
* @param mixed $offset
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->array[$offset]);
}
/**
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset The offset to unset.
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->array[$offset]);
}
/**
* {@inheritDoc}
*/
#[\ReturnTypeWillChange]
public function count()
{
return count($this->array);
}
}
@@ -0,0 +1,214 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\ArrayList;
use ArrayAccess;
use Countable;
use IteratorAggregate;
use Seboettg\Collection\CollectionInterface;
use Traversable;
/**
* Interface ArrayListInterface
* @package Seboettg\Collection\ArrayList
*/
interface ArrayListInterface extends CollectionInterface, Traversable, IteratorAggregate, ArrayAccess, Countable, ToArrayInterface
{
/**
* returns element with key $key
* @param $key
* @return mixed|null
*/
public function get($key);
/**
* Inserts or replaces the element at the specified position in this list with the specified element.
*
* @param $key
* @param $element
* @return ArrayListInterface
*/
public function set($key, $element): ArrayListInterface;
/**
* Returns the value of the array element that's currently being pointed to by the
* internal pointer. It does not move the pointer in any way. If the
* internal pointer points beyond the end of the elements list or the array is
* empty, current returns false.
*
* @return mixed|false
*/
public function current();
/**
* Advance the internal array pointer of an array.
* Returns the array value in the next place that's pointed to by the
* internal array pointer, or false if there are no more elements.
*
* @return mixed|false
*/
public function next();
/**
* Rewind the internal array pointer.
* Returns the array value in the previous place that's pointed to by
* the internal array pointer, or false if there are no more
*
* @return mixed|false
*/
public function prev();
/**
* @param array $array
* @return ArrayListInterface
*/
public function replace(array $array): ArrayListInterface;
/**
* Appends the passed element to the end of this list.
*
* @param $element
* @return ArrayListInterface
*/
public function append($element): ArrayListInterface;
/**
* Inserts the specified element at the specified position in this list. If another element already exist at the
* specified position the affected positions will transformed into a numerated array. As well the existing element
* as the specified element will be appended to this array.
*
* @param $key
* @param $element
* @return ArrayListInterface
*/
public function add($key, $element): ArrayListInterface;
/**
* Removes the element at the specified position in this list.
*
* @param $key
* @return ArrayListInterface
*/
public function remove($key): ArrayListInterface;
/**
* Returns true if an element exists on the specified position.
*
* @param mixed $key
* @return bool
*/
public function hasKey($key): bool;
/**
* Returns true if the passed element already exists in this list, otherwise false.
*
* @param string $element
* @return bool
*/
public function hasElement($element): bool;
/**
* Returns the first element in this list
* @return mixed
*/
public function first();
/**
* Returns the last element in this list
* @return mixed
*/
public function last();
/**
* alias of replace function
* @param array $array
* @return ArrayListInterface
*/
public function setArray(array $array): ArrayListInterface;
/**
* flush array list
*
* @return ArrayListInterface
*/
public function clear(): ArrayListInterface;
/**
* Shuffles this list (randomizes the order of the elements in). It uses the PHP function shuffle
* @see http://php.net/manual/en/function.shuffle.php
* @return ArrayListInterface
*/
public function shuffle(): ArrayListInterface;
/**
* returns a clone of this ArrayList, filtered by the given closure function
* @param callable $filterFunction
* @return ArrayListInterface
*/
public function filter(callable $filterFunction): ArrayListInterface;
/**
* returns a clone of this ArrayList, filtered by the given array keys
* @param array $keys
* @return ArrayListInterface
*/
public function filterByKeys(array $keys): ArrayListInterface;
/**
* Merges the elements of the passed list together with this list so that the values of the passed list are appended
* to the end of the this list
* @param ArrayListInterface $list
* @return void
*/
public function merge(ArrayListInterface $list): void;
/**
* returns a new ArrayList containing all the elements of this ArrayList after applying the callback function to each one.
* @param callable $mapFunction
* @return ArrayListInterface
*/
public function map(callable $mapFunction): ArrayListInterface;
/**
* Same as <code>map</code> but removes null values from the new list
* @param callable $mapFunction
* @return ArrayListInterface
*/
public function mapNotNull(callable $mapFunction): ArrayListInterface;
/**
* Returns a new ArrayList containing an one-dimensional array of all elements of this ArrayList. Keys are going lost.
* @return ArrayListInterface
*/
public function flatten(): ArrayListInterface;
/**
* Expects a callable function which collects the elements of this list and returns any object. The callable
* function gets passed the entire array of the list
*
* @param callable $collectionFunction
* @return mixed
*/
public function collect(callable $collectionFunction);
/**
* Tries to convert each element of the list to a string and concatenates them with given delimiter.
* Throws a <code>NotConvertibleToStringException</code> if any of the objects in the list is not a string or is not
* convertible to string.
*
* @param string $delimiter
* @throws NotConvertibleToStringException
* @return string
*/
public function collectToString(string $delimiter): string;
}
@@ -0,0 +1,302 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\ArrayList;
use function Seboettg\Collection\ArrayList\strval;
/**
* Trait ArrayListTrait
* @package Seboettg\Collection
* @author Sebastian Böttger <seboettg@gmail.com>
* @property $array Base array of this data structure
*/
trait ArrayListTrait
{
use ArrayAccessTrait;
/**
* flush array list
*
* @return ArrayListInterface|ArrayListTrait
*/
public function clear(): ArrayListInterface
{
$this->array = [];
return $this;
}
/**
* {@inheritdoc}
*/
public function get($key)
{
return $this->array[$key] ?? null;
}
/**
* {@inheritdoc}
*/
public function current()
{
return current($this->array);
}
/**
* {@inheritdoc}
*/
public function next()
{
return next($this->array);
}
/**
* {@inheritdoc}
*/
public function prev()
{
return prev($this->array);
}
/**
* @param $key
* @param $element
* @return ArrayListInterface|ArrayListTrait
*/
public function set($key, $element): ArrayListInterface
{
$this->array[$key] = $element;
return $this;
}
/**
* @param $element
* @return ArrayListInterface|ArrayListTrait
*/
public function append($element): ArrayListInterface
{
$this->array[] = $element;
return $this;
}
/**
* @param $key
* @param $element
* @return ArrayListInterface|ArrayListTrait
*/
public function add($key, $element): ArrayListInterface
{
if (!array_key_exists($key, $this->array)) {
$this->array[$key] = $element;
} elseif (is_array($this->array[$key])) {
$this->array[$key][] = $element;
} else {
$this->array[$key] = [$this->array[$key], $element];
}
return $this;
}
/**
* @param $key
* @return ArrayListInterface|ArrayListTrait
*/
public function remove($key): ArrayListInterface
{
unset($this->array[$key]);
return $this;
}
/**
* {@inheritdoc}
*/
public function hasKey($key): bool
{
return array_key_exists($key, $this->array);
}
/**
* {@inheritdoc}
*/
public function hasElement($value): bool
{
$result = in_array($value, $this->array, true);
return ($result !== false);
}
/**
* Returns the first element
* @return mixed
*/
public function first()
{
reset($this->array);
return $this->array[key($this->array)];
}
/**
* Returns the last element
* @return mixed
*/
public function last()
{
$item = end($this->array);
reset($this->array);
return $item;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->array;
}
/**
* Shuffles this list (randomizes the order of the elements in). It uses the PHP function shuffle
* @see http://php.net/manual/en/function.shuffle.php
* @return ArrayListInterface|ArrayListTrait
*/
public function shuffle(): ArrayListInterface
{
shuffle($this->array);
return $this;
}
/**
* returns a clone of this ArrayList, filtered by the given closure function
* @param callable $filterFunction
* @return ArrayListInterface|ArrayListTrait
*/
public function filter(callable $filterFunction): ArrayListInterface
{
$newInstance = new static();
$newInstance->setArray(array_filter($this->array, $filterFunction));
return $newInstance;
}
/**
* @param array $array
* @return ArrayListInterface|ArrayListTrait
*/
public function setArray(array $array): ArrayListInterface
{
return $this->replace($array);
}
/**
* @param array $data
* @return ArrayListInterface|ArrayListTrait
*/
public function replace(array $data): ArrayListInterface
{
$this->array = $data;
return $this;
}
/**
* returns a new ArrayList, elements are filtered by the given array keys
* @param array $keys
* @return ArrayListInterface|ArrayListTrait
*/
public function filterByKeys(array $keys): ArrayListInterface
{
$newInstance = new static();
$newInstance->setArray(array_filter($this->array, function ($key) use ($keys) {
return in_array($key, $keys);
}, ARRAY_FILTER_USE_KEY));
return $newInstance;
}
/**
* returns a new ArrayList containing all the elements of this ArrayList after applying the callback function to each one.
* @param callable $mapFunction
* @return ArrayListInterface|ArrayListTrait
*/
public function map(callable $mapFunction): ArrayListInterface
{
$newInstance = new static();
$newInstance->setArray(array_map($mapFunction, $this->array));
return $newInstance;
}
/**
* @inheritDoc
* @param callable $mapFunction
* @return ArrayListInterface|ArrayListTrait
*/
public function mapNotNull(callable $mapFunction): ArrayListInterface
{
$newInstance = new static();
$newInstance->setArray(array_values(array_filter(array_map($mapFunction, $this->array), function ($item) {
return $item !== null;
})));
return $newInstance;
}
/**
* Returns a new ArrayList containing an one-dimensional array of all elements of this ArrayList. Keys are going lost.
* @return ArrayListInterface|ArrayListTrait
*/
public function flatten(): ArrayListInterface
{
$flattenedArray = [];
array_walk_recursive($this->array, function ($item) use (&$flattenedArray) {
$flattenedArray[] = $item;
});
$newInstance = new static();
$newInstance->setArray($flattenedArray);
return $newInstance;
}
/**
* @inheritDoc
* @param ArrayListInterface $list
*/
public function merge(ArrayListInterface $list): void
{
$this->array = array_merge($this->array, $list->toArray());
}
/**
* @inheritDoc
* @param callable $collectFunction
* @return mixed
*/
public function collect(callable $collectFunction)
{
return $collectFunction($this->array);
}
/**
* @inheritDoc
* @param string $delimiter
* @return string
*/
public function collectToString(string $delimiter): string
{
return implode($delimiter, $this->map(function ($item) {
if (is_scalar($item)) {
return strval($item);
} else if (is_object($item)) {
if (method_exists($item, "toString")) {
return $item->toString();
}
}
throw new NotConvertibleToStringException(
"Couldn't collectToString since any object in list contains objects which are not " .
"convertible to string.");
})->toArray());
}
}
@@ -0,0 +1,25 @@
<?php
namespace Seboettg\Collection\ArrayList;
final class Functions
{
public static function strval($value): string {
if (is_double($value)) {
$str = \strval($value);
if (strlen($str) == 1) {
return sprintf("%1\$.1f",$value);
}
return \strval($value);
}
if (is_bool($value)) {
return $value ? "true" : "false";
}
return "$value";
}
}
function strval($value): string {
return Functions::strval($value);
}
@@ -0,0 +1,10 @@
<?php
namespace Seboettg\Collection\ArrayList;
use Exception;
class NotConvertibleToStringException extends Exception
{
}
@@ -0,0 +1,29 @@
<?php
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\ArrayList;
/**
*
* ToArrayInterface
*
* @package Seboettg\Collection
*
* @author Sebastian Böttger <seboettg@gmail.com>
*/
interface ToArrayInterface
{
/**
* Get the array representation of an object
*
* @return array
*/
public function toArray(): array;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection;
/**
* Parent interface for all collection interfaces (ArrayListInterface, QueueInterface, StackInterface)
* @package Seboettg\Collection
*
* @author Sebastian Böttger <seboettg@gmail.com>
*/
interface CollectionInterface
{
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection;
use Seboettg\Collection\ArrayList\ArrayListInterface;
use Seboettg\Collection\Comparable\Comparator;
/**
* Class Collections
* @package Seboettg\Collection
*
* @author Sebastian Böttger <seboettg@gmail.com>
*/
class Collections
{
/**
* Sorts the specified list according to the order induced by the specified comparator. All elements in the list
* must be mutually comparable.
*
* @param ArrayListInterface $list
* @param Comparator $comparator
* @return ArrayListInterface
*/
public static function sort(ArrayListInterface $list, Comparator $comparator): ArrayListInterface
{
$array = $list->toArray();
usort($array, [$comparator, "compare"]);
$list->replace($array);
return $list;
}
}
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Comparable;
/**
* Comparable Interface for elements as part of an ArrayList.
*
* This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred
* to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.
*
* @package Seboettg\Collection
* @author Sebastian Böttger <seboettg@gmail.com>
*/
interface Comparable
{
/**
* Compares this object with the specified object for order. Returns a negative integer, zero, or a positive
* integer as this object is less than, equal to, or greater than the specified object.
*
* The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.
*
* @param Comparable $b
* @return int
*/
public function compareTo(Comparable $b): int;
}
@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2016 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Comparable;
/**
* Abstract class Comparator. When extending this class the compare function must be implemented. compare() is a
* comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a
* sort method to allow precise control over the sort order.
*
* @package Seboettg\Collection
*
* @author Sebastian Böttger <seboettg@gmail.de>
*/
abstract class Comparator
{
/**
* static constant for sorting order ascending
*/
const ORDER_ASC = "ASC";
/**
* static constant for sorting order descending
*/
const ORDER_DESC = "DESC";
/**
* static constant for a custom sorting order
*/
const ORDER_CUSTOM = "CUSTOM";
/**
* defines the order (ascending|descending) for a comparison
*
* @var string
*/
protected $sortingOrder;
/**
* object/array which can be used to define a custom order
* @var mixed
*/
protected $customOrder;
/**
* Comparator constructor.
* @param string $sortingOrder defines the order (ascending|descending) for a comparison
* @param mixed $customOrder
*/
public function __construct($sortingOrder = self::ORDER_ASC, $customOrder = null)
{
$this->sortingOrder = $sortingOrder;
$this->customOrder = $customOrder;
}
/**
* Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*
* @param Comparable $a
* @param Comparable $b
* @return int
*/
public abstract function compare(Comparable $a, Comparable $b): int;
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection;
use Seboettg\Collection\Queue\QueueInterface;
use Seboettg\Collection\Queue\QueueTrait;
/**
* Class Queue
* @package Seboettg\Collection
* @author Sebastian Böttger <boettger@hebis.uni-frankfurt.de>
*/
class Queue implements QueueInterface
{
use QueueTrait;
/**
* @var array
*/
protected $array;
/**
* Queue constructor.
*/
public function __construct()
{
$this->array = [];
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Queue;
use Countable;
use Seboettg\Collection\CollectionInterface;
/**
* Interface QueueInterface
* @package Seboettg\Collection\Queue
* @author Sebastian Böttger <seboettg@gmail.com>
*/
interface QueueInterface extends CollectionInterface, Countable
{
/**
* Adds an element to the queue
* @param $element
* @return mixed
*/
public function enqueue($element);
/**
* Dequeues an element from the queue
* @return mixed
*/
public function dequeue();
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Queue;
/**
* Trait QueueTrait
* @property $array Base array of this data structure
* @package Seboettg\Collection\Queue
*/
trait QueueTrait
{
/**
* {@inheritdoc}
*/
public function enqueue($item)
{
$this->array = array_merge([$item], $this->array);
return $this;
}
/**
* {@inheritdoc}
*/
public function dequeue()
{
return array_pop($this->array);
}
/**
* {@inheritdoc}
*/
public function count()
{
return count($this->array);
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection;
use Seboettg\Collection\Stack\StackInterface;
use Seboettg\Collection\Stack\StackTrait;
/**
* Class Stack
* @package Seboettg\Collection
* @author Sebastian Böttger <seboettg@gmail.com>
*/
class Stack implements StackInterface
{
use StackTrait;
/**
* @var array
*/
protected $array;
/**
* Stack constructor.
*/
public function __construct()
{
$this->array = [];
}
}
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Stack;
use Countable;
use Seboettg\Collection\CollectionInterface;
/**
* Interface StackInterface
* @package Seboettg\Collection\Stack
* @author Sebastian Böttger <seboettg@gmail.com>
*/
interface StackInterface extends CollectionInterface, Countable
{
/**
* Pushes an element onto the top of this stack. This has exactly the same effect as:
* @param mixed $element
* @return StackInterface
*/
public function push($element);
/**
* Removes the element at the top of this stack and returns that object as the value of this function.
* @return mixed
*/
public function pop();
/**
* Returns the element at the top of this stack without removing it from the stack.
* @return mixed
*/
public function peek();
/**
* Returns the position where an element is on this stack. If the passed element occurs as an element in this stack,
* this method returns the distance from the top of the stack of the occurrence nearest the top of the stack;
* the topmost element on the stack is considered to be at distance 1. If the passed element does not occur in this
* stack, this method returns 0.
*
* @param $element
* @return int
*/
public function search($element);
}
@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2018 Sebastian Böttger <seboettg@gmail.com>
* You may use, distribute and modify this code under the
* terms of the MIT license.
*
* You should have received a copy of the MIT license with
* this file. If not, please visit: https://opensource.org/licenses/mit-license.php
*/
namespace Seboettg\Collection\Stack;
/**
* Trait StackTrait
* @package Seboettg\Collection
* @author Sebastian Böttger <seboettg@gmail.com>
* @property $array Base array of this data structure
*/
trait StackTrait
{
/**
* {@inheritdoc}
*/
public function push($item)
{
$this->array[] = $item;
return $this;
}
/**
* {@inheritdoc}
*/
public function pop()
{
return array_pop($this->array);
}
/**
* {@inheritdoc}
*/
public function peek()
{
return end($this->array);
}
/**
* {@inheritdoc}
*/
public function search($element)
{
$pos = array_search($element, $this->array);
if ($pos === false) {
return 0;
}
$count = $this->count();
return $count - $pos;
}
/**
* {@inheritdoc}
*/
public function count()
{
return count($this->array);
}
}