Compare commits

..

15 Commits
2.x ... master

@ -2,10 +2,20 @@
"name": "jrosset/collections",
"description": "Classes for collections",
"keywords": [ ],
"type": "library",
"config": {
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"minimum-stability": "stable",
"require": {
"php": "^7.4 || ^8.0"
"php": "^8.1"
},
"autoload": {
"psr-4": {
@ -30,4 +40,4 @@
"docs": "https://git.jrosset.ovh/jrosset/PhpCollections/wiki",
"source": "https://git.jrosset.ovh/jrosset/PhpCollections"
}
}
}

@ -17,40 +17,40 @@ class Collection extends ImmutableCollection implements ICollection {
/**
* @inheritDoc
*/
public function set ($key, $value) {
public function set ($key, $value): static {
return $this->_set($key, $value);
}
/**
* @inheritDoc
*/
public function merge (IImmutableCollection ...$collections) {
public function merge (IImmutableCollection ...$collections): static {
return $this->_merge(...$collections);
}
/**
* @inheritDoc
*/
public function add (...$values) {
public function add (...$values): static {
return $this->_add(...$values);
}
/**
* @inheritDoc
*/
public function addCollection (IImmutableCollection ...$collections) {
public function addCollection (IImmutableCollection ...$collections): static {
return $this->_addCollection(...$collections);
}
/**
* @inheritDoc
*/
public function prepend (...$values) {
public function prepend (...$values): static {
array_unshift($this->elements, ...$values);
return $this;
}
/**
* @inheritDoc
*/
public function prependCollection (IImmutableCollection ...$collections) {
public function prependCollection (IImmutableCollection ...$collections): static {
$prepend = array_merge(
...array_map(
function (IImmutableCollection $collection): array {
@ -65,21 +65,21 @@ class Collection extends ImmutableCollection implements ICollection {
/**
* @inheritDoc
*/
public function clear () {
public function clear (): static {
$this->_initialize();
return $this;
}
/**
* @inheritDoc
*/
public function remove ($key) {
public function remove ($key): static {
unset($this->elements[$this->_normalizeKey($key)]);
return $this;
}
/**
* @inheritDoc
*/
public function removeValue ($value, bool $strict = false) {
public function removeValue ($value, bool $strict = false): static {
foreach ($this->elements as $currentKey => $currentValue) {
if (($strict && $value === $currentValue) || (!$strict && $value == $currentValue)) {
unset($this->elements[$currentKey]);
@ -112,37 +112,41 @@ class Collection extends ImmutableCollection implements ICollection {
/**
* @inheritDoc
*/
public function offsetSet ($offset, $value): void {
public function offsetSet (mixed $offset, mixed $value): void {
$this->set($offset, $value);
}
/**
* @inheritDoc
*/
public function offsetUnset ($offset): void {
public function offsetUnset (mixed $offset): void {
$this->remove($offset);
}
/**
* @inheritDoc
*/
public function sliceSelf (int $offset, ?int $length = null) {
$this->_checkOffset($offset);
$this->elements = array_slice($this->elements, $offset, $length, true);
public function sliceSelf (int $offset, ?int $length = null): static {
if ($this->count() === 0) {
$this->elements = [];
}
else {
$this->_checkOffset($offset);
$this->elements = array_slice($this->elements, $offset, $length, true);
}
return $this;
}
/**
* @inheritDoc
*/
public function filterSelf (Closure $filter) {
public function filterSelf (Closure $filter): static {
$this->elements = array_filter($this->elements, $filter);
return $this;
}
/**
* @inheritDoc
*/
public function removeEmpties () {
public function removeEmpties (): static {
return $this->filterSelf(function ($value) {
return empty($value);
});
@ -150,22 +154,22 @@ class Collection extends ImmutableCollection implements ICollection {
/**
* @inheritDoc
*/
public function mapSelf (Closure $process) {
$this->elements = array_map($process, $this->elements);
public function mapSelf (Closure $process): static {
$this->elements = $this->map($process)->elements;
return $this;
}
/**
* @inheritDoc
*/
public function sortSelf ($sorter = null) {
public function sortSelf (Closure|IComparator|null $sorter = null): static {
uasort($this->elements, self::_normalizeSorter($sorter));
return $this;
}
/**
* @inheritDoc
*/
public function sortSelfByKey ($sorter) {
public function sortSelfByKey (Closure|IComparator $sorter): static {
uksort($this->elements, self::_normalizeSorter($sorter));
return $this;
}

@ -3,8 +3,8 @@
namespace jrosset\Collections;
use Closure;
use Exception;
use OutOfBoundsException;
use Throwable;
/**
* Interface for a collection
@ -22,20 +22,16 @@ interface ICollection extends IImmutableCollection {
* @param TValue $value The value
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function set ($key, $value);
public function set ($key, $value): static;
/**
* Merge one or multiple collections into the current one
*
* @param IImmutableCollection<TKey, TValue> ...$collections The collections to merge
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function merge (IImmutableCollection ...$collections);
public function merge (IImmutableCollection ...$collections): static;
/**
* Add one or multiple values
@ -43,20 +39,16 @@ interface ICollection extends IImmutableCollection {
* @param TValue ...$values The values
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function add (...$values);
public function add (...$values): static;
/**
* Add the <b>values</b> of one or multiple collections
*
* @param IImmutableCollection<TKey, TValue> ...$collections The collections to add
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function addCollection (IImmutableCollection ...$collections);
public function addCollection (IImmutableCollection ...$collections): static;
/**
* Add one or multiple values at the beginning of the current collection
@ -64,39 +56,31 @@ interface ICollection extends IImmutableCollection {
* @param TValue ...$values The values
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function prepend (...$values);
public function prepend (...$values): static;
/**
* Add the <b>values</b> of one or multiple collections at the beginning of the current collection
*
* @param IImmutableCollection<TKey, TValue> ...$collections The collections to add
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function prependCollection (IImmutableCollection ...$collections);
public function prependCollection (IImmutableCollection ...$collections): static;
/**
* Empty the collection
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function clear ();
public function clear (): static;
/**
* Remove a value from it's key
*
* @param TKey $key The key
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function remove ($key);
public function remove ($key): static;
/**
* Delete all instances of a value
*
@ -104,10 +88,8 @@ interface ICollection extends IImmutableCollection {
* @param bool $strict Strict comparison ?
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function removeValue ($value, bool $strict = false);
public function removeValue ($value, bool $strict = false): static;
/**
* Get and remove the first element
@ -137,10 +119,8 @@ interface ICollection extends IImmutableCollection {
* @return $this
*
* @throws OutOfBoundsException If the offset is not valid
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function sliceSelf (int $offset, ?int $length = null);
public function sliceSelf (int $offset, ?int $length = null): static;
/**
* Keep only elements that satisfy predicate $filter
@ -148,30 +128,24 @@ interface ICollection extends IImmutableCollection {
* @param Closure(TKey, TValue):bool $filter The filtering predicate
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function filterSelf (Closure $filter);
public function filterSelf (Closure $filter): static;
/**
* Keep only non-empty elements
*
* Use {@see https://www.php.net/manual/function.empty.php empty} to check if element is empty or not
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function removeEmpties ();
public function removeEmpties (): static;
/**
* Applied <b>$process</b> on all elements
*
* @param Closure(TKey, TValue): TValue $process The process function to apply on each element
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function mapSelf (Closure $process);
public function mapSelf (Closure $process): static;
/**
* Sort the elements (by value)
@ -184,11 +158,9 @@ interface ICollection extends IImmutableCollection {
*
* @return $this
*
* @throws Exception If an error occurs
*
* @noinspection PhpMissingReturnTypeInspection
* @throws Throwable If an error occurs
*/
public function sortSelf ($sorter = null);
public function sortSelf (Closure|IComparator|null $sorter = null): static;
/**
* Sort the elements by key
*
@ -199,9 +171,7 @@ interface ICollection extends IImmutableCollection {
*
* @return $this
*
* @throws Exception If an error occurs
*
* @noinspection PhpMissingReturnTypeInspection
* @throws Throwable If an error occurs
*/
public function sortSelfByKey ($sorter);
public function sortSelfByKey (Closure|IComparator $sorter): static;
}

@ -8,7 +8,6 @@ use Countable;
use IteratorAggregate;
use JsonSerializable;
use OutOfBoundsException;
use Serializable;
use Throwable;
/**
@ -21,7 +20,7 @@ use Throwable;
* @implements ArrayAccess<TKey, TValue>
* @implements IArrayCast<TKey, TValue>
*/
interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Serializable, Countable, ArrayAccess, IArrayCast {
interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Countable, ArrayAccess, IArrayCast {
/**
* Checks if the collection is empty
*
@ -131,10 +130,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @return static<TKey, TValue> The result collection
*
* @throws OutOfBoundsException If the offset is not valid
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function slice (int $offset, ?int $length = null);
public function slice (int $offset, ?int $length = null): static;
/**
* Get a collection of all elements that satisfy predicate $filter
@ -142,20 +139,16 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param Closure(TKey, TValue):bool $filter The filtering predicate
*
* @return static<TKey, TValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function filter (Closure $filter);
public function filter (Closure $filter): static;
/**
* Get a collection of all not empty elements
*
* Use {@see https://www.php.net/manual/function.empty.php empty} to check if element is empty or not
*
* @return static<TKey, TValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function withoutEmpties ();
public function withoutEmpties (): static;
/**
* A new collection with <b>$process</b> applied on all elements
*
@ -164,10 +157,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param Closure(TKey, TValue): TResultValue $process The process function to apply on each element
*
* @return static<TKey, TResultValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function map (Closure $process);
public function map (Closure $process): static;
/**
* Get a collection with the elements sorted (by value)
@ -181,10 +172,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @return static<TKey, TValue> The result collection
*
* @throws Throwable If an error occurs
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function sort ($sorter = null);
public function sort (Closure|IComparator|null $sorter = null): static;
/**
* Get a collection with the elements sorted by key
*
@ -196,10 +185,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @return static<TKey, TValue> The result collection
*
* @throws Throwable If an error occurs
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function sortByKey ($sorter);
public function sortByKey (Closure|IComparator $sorter): static;
/**
* The list of all keys
@ -211,10 +198,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* The list of all values
*
* @return static<int, TValue> The list of all values
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function values ();
public function values (): static;
/**
* Join all values with a separator
@ -231,10 +216,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param string $separator The split separator
*
* @return static<int, string> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public static function split (string $value, string $separator);
public static function split (string $value, string $separator): static;
/**
* Create a collection filled with the same element
@ -243,10 +226,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param TValue $value The value to fill the collection
*
* @return static<int, TValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public static function fill (int $size, $value);
public static function fill (int $size, $value): static;
/**
* Create a collection filled with the same element, using a list of keys
*
@ -254,10 +235,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param TValue $value The value to fill the collection
*
* @return static<TKey, TValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public static function fillWithKeys (IImmutableCollection $keys, $value);
public static function fillWithKeys (IImmutableCollection $keys, $value): static;
/**
* Merge the current collection with one or multiple collections
@ -265,8 +244,6 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @param IImmutableCollection<TKey, TValue> ...$collections The other collections to merge
*
* @return static<TKey, TValue> The result collection
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function mergeWith (IImmutableCollection ...$collections);
public function mergeWith (IImmutableCollection ...$collections): static;
}

@ -6,6 +6,7 @@ use ArrayIterator;
use Closure;
use InvalidArgumentException;
use OutOfBoundsException;
use ReflectionFunction;
use Traversable;
/**
@ -63,10 +64,8 @@ class ImmutableCollection implements IImmutableCollection {
* @return $this
*
* @internal
*
* @noinspection PhpMissingReturnTypeInspection
*/
protected function _set ($key, $value) {
protected function _set ($key, $value): static {
$this->elements[$this->_normalizeKey($key)] = $value;
return $this;
}
@ -78,10 +77,8 @@ class ImmutableCollection implements IImmutableCollection {
* @return $this
*
* @internal
*
* @noinspection PhpMissingReturnTypeInspection
*/
protected function _merge (IImmutableCollection ...$collections) {
protected function _merge (IImmutableCollection ...$collections): static {
foreach ($collections as $collection) {
foreach ($collection as $key => $value) {
$this->_set($key, $value);
@ -97,10 +94,8 @@ class ImmutableCollection implements IImmutableCollection {
* @return $this
*
* @internal
*
* @noinspection PhpMissingReturnTypeInspection
*/
protected function _add (...$values) {
protected function _add (...$values): static {
foreach ($values as $value) {
$this->elements[] = $value;
}
@ -112,10 +107,8 @@ class ImmutableCollection implements IImmutableCollection {
* @param IImmutableCollection ...$collections The collections to add
*
* @return $this
*
* @noinspection PhpMissingReturnTypeInspection
*/
protected function _addCollection (IImmutableCollection ...$collections) {
protected function _addCollection (IImmutableCollection ...$collections): static {
foreach ($collections as $collection) {
foreach ($collection as $value) {
$this->_add($value);
@ -158,25 +151,25 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function offsetExists ($offset): bool {
public function offsetExists (mixed $offset): bool {
return $this->exists($offset);
}
/**
* @inheritDoc
*/
public function offsetGet ($offset) {
public function offsetGet (mixed $offset): mixed {
return $this->get($offset);
}
/**
* @inheritDoc
*/
public function offsetSet ($offset, $value): void {
public function offsetSet (mixed $offset, mixed $value): void {
throw new ImmutableException();
}
/**
* @inheritDoc
*/
public function offsetUnset ($offset): void {
public function offsetUnset (mixed $offset): void {
throw new ImmutableException();
}
@ -191,16 +184,14 @@ class ImmutableCollection implements IImmutableCollection {
];
}
/**
* @inheritDoc
*/
public function serialize (): ?string {
return serialize($this->elements);
}
/**
* @inheritDoc
* {@see https://www.php.net/manual/function.unserialize.php Unserialize} from the list of serialized properties
*
* @param array $data The list of serialized properties
*
* @return void
*/
public function unserialize ($data) {
$this->_initialize(unserialize($data));
public function __unserialize (array $data): void {
$this->_initialize($data['elements']);
}
/**
@ -239,7 +230,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function get ($key) {
public function get ($key): mixed {
return $this->elements[$this->_normalizeKey($key)] ?? null;
}
/**
@ -298,10 +289,13 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function slice (int $offset, ?int $length = null) {
$this->_checkOffset($offset);
public function slice (int $offset, ?int $length = null): static {
$output = new static();
if ($this->count() === 0) {
return $output;
}
$this->_checkOffset($offset);
$currentIndex = 0;
foreach ($this->elements as $key => $value) {
@ -321,7 +315,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function filter (Closure $filter) {
public function filter (Closure $filter): static {
$output = new static();
foreach ($this->elements as $key => $value) {
if (!$filter($key, $value)) {
@ -334,7 +328,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function withoutEmpties () {
public function withoutEmpties (): static {
return $this->filter(function ($value) {
return empty($value);
});
@ -342,10 +336,21 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function map (Closure $process) {
public function map (Closure $process): static {
//region Regarde si $process doit être appelée avec la clé en plus de la valeur
$callProcessWithKey = false;
/** @noinspection PhpUnhandledExceptionInspection */
$processReflection = new ReflectionFunction($process);
if (count($processReflection->getParameters()) >= 2) {
if (!$processReflection->getParameters()[1]->isDefaultValueAvailable()) {
$callProcessWithKey = true;
}
}
//endregion
$output = new static();
foreach ($this->elements as $key => $value) {
$output->_set($key, $process($key, $value));
$output->_set($key, $callProcessWithKey ? $process($key, $value) : $process($value));
}
return $output;
}
@ -353,7 +358,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function sort ($sorter = null) {
public function sort (Closure|IComparator|null $sorter = null): static {
$elements = $this->toArray();
uasort($elements, self::_normalizeSorter($sorter));
@ -362,7 +367,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function sortByKey ($sorter) {
public function sortByKey (Closure|IComparator $sorter): static {
$elements = $this->toArray();
uksort($elements, self::_normalizeSorter($sorter));
@ -384,7 +389,7 @@ class ImmutableCollection implements IImmutableCollection {
* <br>= 0 if value1 equals value2
* <br>&gt; 0 if value1 is after value2
*/
public static function _normalizeSorter ($sorter): Closure {
public static function _normalizeSorter (Closure|IComparator|null $sorter): Closure {
if ($sorter === null) {
return function (IComparable $value1, IComparable $value2): int {
return $value1->compareTo($value2);
@ -409,14 +414,14 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function values () {
public function values (): static {
return new static(array_values($this->elements));
}
/**
* @inheritDoc
*/
public function jsonSerialize () {
public function jsonSerialize (): mixed {
return $this->elements;
}
@ -429,14 +434,14 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public static function split (string $value, string $separator) {
public static function split (string $value, string $separator): static {
return new static (explode($separator, $value));
}
/**
* @inheritDoc
*/
public static function fill (int $size, $value) {
public static function fill (int $size, $value): static {
$keys = new ImmutableCollection();
for ($curr = 0; $curr < $size; $curr++) {
$keys->_add($curr);
@ -447,7 +452,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public static function fillWithKeys (IImmutableCollection $keys, $value) {
public static function fillWithKeys (IImmutableCollection $keys, $value): static {
$collection = new static();
foreach ($keys as $key) {
$collection->_set($key, $value);
@ -458,7 +463,7 @@ class ImmutableCollection implements IImmutableCollection {
/**
* @inheritDoc
*/
public function mergeWith (IImmutableCollection ...$collections) {
public function mergeWith (IImmutableCollection ...$collections): static {
return (clone $this)->_merge(...$collections);
}
}

@ -7,11 +7,9 @@ namespace jrosset\Collections;
*/
trait TInsensitiveCaseKey {
/**
* Normalize a key
* @inheritDoc
*
* @param array-key $key The key to normalize
*
* @return array-key The normalized key
* @noinspection PhpMissingReturnTypeInspection
*/
protected function _normalizeKey ($key) {
return mb_strtolower($key);

@ -12,7 +12,7 @@ trait TUniqueValues {
/**
* @inheritDoc
*/
protected function _set ($key, $value): self {
protected function _set ($key, $value): static {
if ($this->contains($value)) {
return $this;
}
@ -23,7 +23,7 @@ trait TUniqueValues {
/**
* @inheritDoc
*/
protected function _add (...$values): self {
protected function _add (...$values): static {
foreach ($values as $value) {
if ($this->contains($value)) {
continue;

Loading…
Cancel
Save