Add access with offset and first/last methods

2.x 2.8.0
Julien Rosset 2 years ago
parent c0c03b9cae
commit 63e523f195

@ -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) {
$this->_checkOffset($offset);
$this->elements = array_slice($this->elements, $offset, $length, true);
return $this;
}

@ -4,6 +4,7 @@ namespace jrosset\Collections;
use Closure;
use Exception;
use OutOfBoundsException;
/**
* Interface for a collection
@ -108,6 +109,23 @@ interface ICollection extends IImmutableCollection {
*/
public function removeValue ($value, bool $strict = false);
/**
* 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
*
@ -118,6 +136,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);

@ -7,6 +7,7 @@ use Closure;
use Countable;
use IteratorAggregate;
use JsonSerializable;
use OutOfBoundsException;
use Serializable;
use Throwable;
@ -54,6 +55,17 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @return TValue|null The value
*/
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
*
@ -63,6 +75,50 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
* @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
@ -74,6 +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);

@ -5,6 +5,7 @@ namespace jrosset\Collections;
use ArrayIterator;
use Closure;
use InvalidArgumentException;
use OutOfBoundsException;
use Traversable;
/**
@ -132,6 +133,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
@ -227,6 +242,14 @@ class ImmutableCollection implements IImmutableCollection {
public function get ($key) {
return $this->elements[$this->_normalizeKey($key)] ?? null;
}
/**
* @inheritDoc
*/
public function getFromOffset (int $offset) {
$this->_checkOffset($offset);
return array_values($this->elements)[$offset];
}
/**
* @inheritDoc
*/
@ -238,11 +261,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) {
$this->_checkOffset($offset);
$output = new static();
$currentIndex = 0;

Loading…
Cancel
Save