Add access with offset and first/last methods

master 3.5.0
Julien Rosset 2 years ago
parent 4da1264ad8
commit 66fe43fef5

@ -88,6 +88,27 @@ class Collection extends ImmutableCollection implements ICollection {
return $this;
}
/**
* @inheritDoc
*/
public function removeFirst () {
$firstKey = $this->firstKey();
$firstValue = $this->get($firstKey);
$this->remove($firstKey);
return $firstValue;
}
/**
* @inheritDoc
*/
public function removeLast () {
$lastKey = $this->lastKey();
$lastValue = $this->get($lastKey);
$this->remove($lastKey);
return $lastValue;
}
/**
* @inheritDoc
*/
@ -105,6 +126,8 @@ class Collection extends ImmutableCollection implements ICollection {
* @inheritDoc
*/
public function sliceSelf (int $offset, ?int $length = null): static {
$this->_checkOffset($offset);
$this->elements = array_slice($this->elements, $offset, $length, true);
return $this;
}

@ -3,6 +3,7 @@
namespace jrosset\Collections;
use Closure;
use OutOfBoundsException;
use Throwable;
/**
@ -90,6 +91,23 @@ interface ICollection extends IImmutableCollection {
*/
public function removeValue ($value, bool $strict = false): static;
/**
* Get and remove the first element
*
* @return TValue The value
*
* @throws OutOfBoundsException If the collection is empty
*/
public function removeFirst ();
/**
* Get and remove the last element
*
* @return TValue The value
*
* @throws OutOfBoundsException If the collection is empty
*/
public function removeLast ();
/**
* Keep only a slice of the collection
*
@ -99,6 +117,8 @@ interface ICollection extends IImmutableCollection {
* @param int|null $length The maximum length. Null if until end of the collection
*
* @return $this
*
* @throws OutOfBoundsException If the offset is not valid
*/
public function sliceSelf (int $offset, ?int $length = null): static;

@ -7,6 +7,7 @@ use Closure;
use Countable;
use IteratorAggregate;
use JsonSerializable;
use OutOfBoundsException;
use Throwable;
/**
@ -52,7 +53,18 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Coun
*
* @return TValue|null The value
*/
public function get ($key): mixed;
public function get ($key);
/**
* Get the value at an offset
*
* @param int $offset The offset
*
* @return TValue The value
*
* @throws OutOfBoundsException If the offset is not valid
*/
public function getFromOffset (int $offset);
/**
* Get the first key of a value or null if not found
*
@ -62,6 +74,50 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Coun
* @return TKey|null
*/
public function key ($value, bool $strict = false);
/**
* Get the key at an offset
*
* @param int $offset The offset
*
* @return TKey The key
*
* @throws OutOfBoundsException If the offset is not valid
*/
public function keyFromOffset (int $offset);
/**
* Get the value of the first element
*
* @return TValue The value
*
* @throws OutOfBoundsException If the collection is empty
*/
public function first ();
/**
* Get the key of the first element
*
* @return TKey The key
*
* @throws OutOfBoundsException If the collection is empty
*/
public function firstKey ();
/**
* Get the value of the last element
*
* @return TValue The value
*
* @throws OutOfBoundsException If the collection is empty
*/
public function last ();
/**
* Get the key of the last element
*
* @return TKey The key
*
* @throws OutOfBoundsException If the collection is empty
*/
public function lastKey ();
/**
* Extract a slice of the collection
@ -72,6 +128,8 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Coun
* @param int|null $length The maximum length. Null if until end of the collection
*
* @return static<TKey, TValue> The result collection
*
* @throws OutOfBoundsException If the offset is not valid
*/
public function slice (int $offset, ?int $length = null): static;

@ -5,6 +5,7 @@ namespace jrosset\Collections;
use ArrayIterator;
use Closure;
use InvalidArgumentException;
use OutOfBoundsException;
use Traversable;
/**
@ -124,6 +125,20 @@ class ImmutableCollection implements IImmutableCollection {
protected function _normalizeKey ($key) {
return $key;
}
/**
* Vérifie un offset (&ge; 0, &lt; {@see static::count()})
*
* @param int $offset L'offset à vérifier
*
* @return void
*
* @throws OutOfBoundsException Si l'offset est invalide
*/
protected function _checkOffset (int $offset): void {
if ($offset < 0 || $offset >= $this->count()) {
throw new OutOfBoundsException('The offset must be between 0 and ' . ($this->count() - 1));
}
}
/**
* @inheritDoc
@ -217,6 +232,14 @@ class ImmutableCollection implements IImmutableCollection {
public function get ($key): mixed {
return $this->elements[$this->_normalizeKey($key)] ?? null;
}
/**
* @inheritDoc
*/
public function getFromOffset (int $offset) {
$this->_checkOffset($offset);
return array_values($this->elements)[$offset];
}
/**
* @inheritDoc
*/
@ -228,11 +251,46 @@ class ImmutableCollection implements IImmutableCollection {
}
return null;
}
/**
* @inheritDoc
*/
public function keyFromOffset (int $offset) {
$this->_checkOffset($offset);
return array_keys($this->elements)[$offset];
}
/**
* @inheritDoc
*/
public function first () {
return $this->getFromOffset(0);
}
/**
* @inheritDoc
*/
public function firstKey () {
return $this->keyFromOffset(0);
}
/**
* @inheritDoc
*/
public function last () {
return $this->getFromOffset($this->count() - 1);
}
/**
* @inheritDoc
*/
public function lastKey () {
return $this->keyFromOffset($this->count() - 1);
}
/**
* @inheritDoc
*/
public function slice (int $offset, ?int $length = null): static {
$this->_checkOffset($offset);
$output = new static();
$currentIndex = 0;

Loading…
Cancel
Save