|
|
@ -5,7 +5,6 @@ namespace jrosset\Collections;
|
|
|
|
use ArrayIterator;
|
|
|
|
use ArrayIterator;
|
|
|
|
use Closure;
|
|
|
|
use Closure;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
use JsonException;
|
|
|
|
|
|
|
|
use Traversable;
|
|
|
|
use Traversable;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -27,28 +26,27 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Initialise a new collection
|
|
|
|
* Initialise a new collection
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param array|Traversable|null $other The initial values
|
|
|
|
* @param iterable|null $other The initial values
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @psalm-param array<TKey, TValue>|Traversable<TKey, TValue>|null
|
|
|
|
* @psalm-param array<TKey, TValue>|Traversable<TKey, TValue>|null $other
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @throws InvalidArgumentException If the initial values aren't valid
|
|
|
|
* @throws InvalidArgumentException If the initial values aren't valid
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function __construct ($other = null) {
|
|
|
|
public function __construct (?iterable $other = null) {
|
|
|
|
$this->_initialize($other);
|
|
|
|
$this->_initialize($other);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Initialise the internals elements
|
|
|
|
* Initialise the internals elements
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param array|Traversable|null $other The initial values
|
|
|
|
* @param iterable|null $other The initial values
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @psalm-param array<TKey, TValue>|Traversable<TKey, TValue>|null
|
|
|
|
* @psalm-param array<TKey, TValue>|Traversable<TKey, TValue>|null $other
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @throws InvalidArgumentException If the initial values aren't valid
|
|
|
|
* @throws InvalidArgumentException If the initial values aren't valid
|
|
|
|
* @internal
|
|
|
|
* @internal
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected function _initialize ($other = null) {
|
|
|
|
protected function _initialize (?iterable $other = null) {
|
|
|
|
$this->elements = [];
|
|
|
|
$this->elements = [];
|
|
|
|
if ($other !== null) {
|
|
|
|
if ($other !== null) {
|
|
|
|
if (!is_array($other) && !$other instanceof Traversable) {
|
|
|
|
if (!is_array($other) && !$other instanceof Traversable) {
|
|
|
@ -73,7 +71,7 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
* @internal
|
|
|
|
* @internal
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected function _set ($key, $value): self {
|
|
|
|
protected function _set (int|string $key, mixed $value): self {
|
|
|
|
$this->elements[$this->_normalizeKey($key)] = $value;
|
|
|
|
$this->elements[$this->_normalizeKey($key)] = $value;
|
|
|
|
return $this;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -103,7 +101,7 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
* @internal
|
|
|
|
* @internal
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected function _add (...$values): self {
|
|
|
|
protected function _add (mixed ...$values): self {
|
|
|
|
foreach ($values as $value) {
|
|
|
|
foreach ($values as $value) {
|
|
|
|
$this->elements[] = $value;
|
|
|
|
$this->elements[] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -134,53 +132,49 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
* @return array-key The normalized key
|
|
|
|
* @return array-key The normalized key
|
|
|
|
* @psalm-return TKey
|
|
|
|
* @psalm-return TKey
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected function _normalizeKey ($key) {
|
|
|
|
protected function _normalizeKey (int|string $key): int|string {
|
|
|
|
return $key;
|
|
|
|
return $key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function getIterator () {
|
|
|
|
public function getIterator (): ArrayIterator {
|
|
|
|
return new ArrayIterator($this->elements);
|
|
|
|
return new ArrayIterator($this->elements);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function offsetExists ($offset): bool {
|
|
|
|
public function offsetExists (mixed $offset): bool {
|
|
|
|
return $this->exists($offset);
|
|
|
|
return $this->exists($offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function offsetGet ($offset) {
|
|
|
|
public function offsetGet (mixed $offset): mixed {
|
|
|
|
return $this->get($offset);
|
|
|
|
return $this->get($offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function offsetSet ($offset, $value): void {
|
|
|
|
public function offsetSet (mixed $offset, mixed $value): void {
|
|
|
|
throw new ImmutableException();
|
|
|
|
throw new ImmutableException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function offsetUnset ($offset): void {
|
|
|
|
public function offsetUnset (mixed $offset): void {
|
|
|
|
throw new ImmutableException();
|
|
|
|
throw new ImmutableException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
public function __serialize (): array {
|
|
|
|
* @inheritDoc
|
|
|
|
return [
|
|
|
|
*/
|
|
|
|
'elements' => $this->elements,
|
|
|
|
public function serialize (): ?string {
|
|
|
|
];
|
|
|
|
return serialize($this->elements);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
public function __unserialize (array $data): void {
|
|
|
|
* @inheritDoc
|
|
|
|
$this->_initialize($data['elements']);
|
|
|
|
*/
|
|
|
|
|
|
|
|
public function unserialize ($data) {
|
|
|
|
|
|
|
|
$this->_initialize(unserialize($data));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -206,26 +200,26 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function exists ($key): bool {
|
|
|
|
public function exists (int|string $key): bool {
|
|
|
|
return isset($this->elements[$this->_normalizeKey($key)]);
|
|
|
|
return isset($this->elements[$this->_normalizeKey($key)]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function contains ($value, bool $strict = false): bool {
|
|
|
|
public function contains (mixed $value, bool $strict = false): bool {
|
|
|
|
return in_array($value, $this->elements, $strict);
|
|
|
|
return in_array($value, $this->elements, $strict);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function get ($key) {
|
|
|
|
public function get (int|string $key): mixed {
|
|
|
|
return $this->elements[$this->_normalizeKey($key)] ?? null;
|
|
|
|
return $this->elements[$this->_normalizeKey($key)] ?? null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function key ($value, bool $strict = false) {
|
|
|
|
public function key (mixed $value, bool $strict = false): int|string|null {
|
|
|
|
foreach ($this->elements as $currentKey => $currentValue) {
|
|
|
|
foreach ($this->elements as $currentKey => $currentValue) {
|
|
|
|
if (($strict && $value === $currentValue) || (!$strict && $value == $currentValue)) {
|
|
|
|
if (($strict && $value === $currentValue) || (!$strict && $value == $currentValue)) {
|
|
|
|
return $currentKey;
|
|
|
|
return $currentKey;
|
|
|
@ -309,11 +303,9 @@ class ImmutableCollection implements IImmutableCollection {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
* @inheritDoc
|
|
|
|
*
|
|
|
|
|
|
|
|
* @throws JsonException
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function jsonSerialize () {
|
|
|
|
public function jsonSerialize (): mixed {
|
|
|
|
return json_encode($this->elements, JSON_THROW_ON_ERROR);
|
|
|
|
return $this->elements;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|