Improved type signatures on XArray methods.
This commit is contained in:
parent
9368523d6b
commit
39232c0662
3 changed files with 99 additions and 72 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.2501.212104
|
||||
0.2501.212344
|
||||
|
|
159
src/XArray.php
159
src/XArray.php
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// XArray.php
|
||||
// Created: 2022-02-02
|
||||
// Updated: 2025-01-18
|
||||
// Updated: 2025-01-21
|
||||
|
||||
namespace Index;
|
||||
|
||||
|
@ -39,7 +39,8 @@ final class XArray {
|
|||
/**
|
||||
* Retrieves the amount of items in a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return int
|
||||
*/
|
||||
public static function count(iterable $iterable): int {
|
||||
|
@ -57,7 +58,8 @@ final class XArray {
|
|||
/**
|
||||
* Checks if a collection has no items.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return bool
|
||||
*/
|
||||
public static function empty(iterable $iterable): bool {
|
||||
|
@ -75,8 +77,9 @@ final class XArray {
|
|||
/**
|
||||
* Checks if an item occurs in a collection
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param mixed $value
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param T $value
|
||||
* @param bool $strict
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -100,12 +103,13 @@ final class XArray {
|
|||
/**
|
||||
* Checks if a key occurs in a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param mixed $key
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param int|string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function containsKey(iterable $iterable, mixed $key): bool {
|
||||
if(is_array($iterable) && (is_string($key) || is_int($key)))
|
||||
public static function containsKey(iterable $iterable, int|string $key): bool {
|
||||
if(is_array($iterable))
|
||||
return array_key_exists($key, $iterable);
|
||||
|
||||
foreach($iterable as $k => $_)
|
||||
|
@ -118,15 +122,16 @@ final class XArray {
|
|||
/**
|
||||
* Retrieves the first key in a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return mixed
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return int|string|null
|
||||
*/
|
||||
public static function firstKey(iterable $iterable): mixed {
|
||||
public static function firstKey(iterable $iterable): int|string|null {
|
||||
if(is_array($iterable))
|
||||
return array_key_first($iterable);
|
||||
|
||||
foreach($iterable as $key => $_)
|
||||
return $key;
|
||||
return is_int($key) || is_string($key) ? $key : null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -134,54 +139,62 @@ final class XArray {
|
|||
/**
|
||||
* Retrieves the last key in a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return mixed
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return int|string|null
|
||||
*/
|
||||
public static function lastKey(iterable $iterable): mixed {
|
||||
public static function lastKey(iterable $iterable): int|string|null {
|
||||
if(is_array($iterable))
|
||||
return array_key_last($iterable);
|
||||
|
||||
$key = null;
|
||||
foreach($iterable as $key => $_);
|
||||
|
||||
return $key;
|
||||
return is_int($key) || is_string($key) ? $key : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a value in a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param mixed $value
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param T $value
|
||||
* @param bool $strict
|
||||
* @return mixed
|
||||
* @return int|string|false
|
||||
*/
|
||||
public static function indexOf(
|
||||
iterable $iterable,
|
||||
mixed $value,
|
||||
bool $strict = false
|
||||
): mixed {
|
||||
): int|string|false {
|
||||
if(is_array($iterable))
|
||||
return array_search($value, $iterable, $strict);
|
||||
|
||||
$return = false;
|
||||
if($strict) {
|
||||
foreach($iterable as $key => $item)
|
||||
if($item === $value)
|
||||
return $key;
|
||||
if($item === $value) {
|
||||
$return = $key;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foreach($iterable as $key => $item)
|
||||
if($item == $value)
|
||||
return $key;
|
||||
if($item == $value) {
|
||||
$return = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return is_int($return) || is_string($return) ? $return : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts unique values from a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param int $type
|
||||
* @return mixed[]
|
||||
* @return T[]
|
||||
*/
|
||||
public static function unique(iterable $iterable, int $type = self::UNIQUE_VALUE): array {
|
||||
if(is_array($iterable))
|
||||
|
@ -199,8 +212,9 @@ final class XArray {
|
|||
/**
|
||||
* Takes values from a collection and discards the keys.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return mixed[]
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return T[]
|
||||
*/
|
||||
public static function reflow(iterable $iterable): array {
|
||||
if(is_array($iterable))
|
||||
|
@ -217,8 +231,9 @@ final class XArray {
|
|||
/**
|
||||
* Puts a collection in reverse order.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return mixed[]
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return T[]
|
||||
*/
|
||||
public static function reverse(iterable $iterable): array {
|
||||
if(is_array($iterable))
|
||||
|
@ -235,9 +250,11 @@ final class XArray {
|
|||
/**
|
||||
* Merges two collections.
|
||||
*
|
||||
* @param mixed[] $iterable1
|
||||
* @param mixed[] $iterable2
|
||||
* @return mixed[]
|
||||
* @template T1
|
||||
* @template T2
|
||||
* @param iterable<T1> $iterable1
|
||||
* @param iterable<T2> $iterable2
|
||||
* @return array<T1|T2>
|
||||
*/
|
||||
public static function merge(iterable $iterable1, iterable $iterable2): array {
|
||||
return array_merge(self::toArray($iterable1), self::toArray($iterable2));
|
||||
|
@ -247,8 +264,8 @@ final class XArray {
|
|||
* Sorts a collection according to a comparer.
|
||||
*
|
||||
* @template T
|
||||
* @param T[] $iterable
|
||||
* @param callable $comparer
|
||||
* @param iterable<T> $iterable
|
||||
* @param callable(T, T): int $comparer
|
||||
* @return T[]
|
||||
*/
|
||||
public static function sort(iterable $iterable, callable $comparer): array {
|
||||
|
@ -270,10 +287,11 @@ final class XArray {
|
|||
/**
|
||||
* Takes a subsection of a collection.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param int $offset
|
||||
* @param int|null $length
|
||||
* @return mixed[]
|
||||
* @return T[]
|
||||
*/
|
||||
public static function slice(iterable $iterable, int $offset, int|null $length = null): array {
|
||||
if(is_array($iterable))
|
||||
|
@ -290,8 +308,9 @@ final class XArray {
|
|||
/**
|
||||
* Converts any iterable to a PHP array.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return mixed[]
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return T[]
|
||||
*/
|
||||
public static function toArray(iterable $iterable): array {
|
||||
if(is_array($iterable))
|
||||
|
@ -308,17 +327,21 @@ final class XArray {
|
|||
/**
|
||||
* Checks if any value in the collection matches a given predicate.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param callable(mixed, mixed): bool $predicate
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param callable(T, int|string): bool $predicate
|
||||
* @return bool
|
||||
*/
|
||||
public static function any(iterable $iterable, callable $predicate): bool {
|
||||
if(is_array($iterable))
|
||||
return array_any($iterable, $predicate);
|
||||
|
||||
foreach($iterable as $key => $value)
|
||||
if($predicate($value, $key))
|
||||
$count = 0;
|
||||
foreach($iterable as $key => $value) {
|
||||
if($predicate($value, is_int($key) || is_string($key) ? $key : $count))
|
||||
return true;
|
||||
++$count;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -326,17 +349,21 @@ final class XArray {
|
|||
/**
|
||||
* Checks if all values in the collection match a given predicate.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param callable(mixed, mixed): bool $predicate
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param callable(T, int|string): bool $predicate
|
||||
* @return bool
|
||||
*/
|
||||
public static function all(iterable $iterable, callable $predicate): bool {
|
||||
if(is_array($iterable))
|
||||
return array_all($iterable, $predicate);
|
||||
|
||||
foreach($iterable as $key => $value)
|
||||
if(!$predicate($value, $key))
|
||||
$count = 0;
|
||||
foreach($iterable as $key => $value) {
|
||||
if(!$predicate($value, is_int($key) || is_string($key) ? $key : $count))
|
||||
return false;
|
||||
++$count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -344,9 +371,10 @@ final class XArray {
|
|||
/**
|
||||
* Gets a subset of a collection based on a given predicate.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param callable(mixed): bool $predicate
|
||||
* @return mixed[]
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param callable(T): bool $predicate
|
||||
* @return T[]
|
||||
*/
|
||||
public static function where(iterable $iterable, callable $predicate): array {
|
||||
$array = [];
|
||||
|
@ -361,9 +389,10 @@ final class XArray {
|
|||
/**
|
||||
* Gets the first item in a collection that matches a given predicate.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param (callable(mixed): bool)|null $predicate
|
||||
* @return mixed
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param (callable(T): bool)|null $predicate
|
||||
* @return ?T
|
||||
*/
|
||||
public static function first(iterable $iterable, ?callable $predicate = null): mixed {
|
||||
if($predicate === null) {
|
||||
|
@ -390,9 +419,10 @@ final class XArray {
|
|||
/**
|
||||
* Gets the last item in a collection that matches a given predicate.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @param (callable(mixed): bool)|null $predicate
|
||||
* @return mixed
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @param (callable(T): bool)|null $predicate
|
||||
* @return ?T
|
||||
*/
|
||||
public static function last(iterable $iterable, ?callable $predicate = null): mixed {
|
||||
if($predicate === null) {
|
||||
|
@ -423,7 +453,7 @@ final class XArray {
|
|||
*
|
||||
* @template T1
|
||||
* @template T2
|
||||
* @param T1[] $iterable
|
||||
* @param iterable<T1> $iterable
|
||||
* @param callable(T1): T2 $selector
|
||||
* @return T2[]
|
||||
*/
|
||||
|
@ -442,10 +472,11 @@ final class XArray {
|
|||
/**
|
||||
* Tries to extract an instance of Iterator from any iterable type.
|
||||
*
|
||||
* @param mixed[] $iterable
|
||||
* @return Iterator
|
||||
* @template T
|
||||
* @param iterable<T> $iterable
|
||||
* @return Iterator<T>
|
||||
*/
|
||||
public static function extractIterator(iterable &$iterable): Iterator {
|
||||
public static function extractIterator(iterable $iterable): Iterator {
|
||||
if($iterable instanceof Iterator)
|
||||
return $iterable;
|
||||
if($iterable instanceof IteratorAggregate)
|
||||
|
@ -459,8 +490,8 @@ final class XArray {
|
|||
/**
|
||||
* Checks if two collections are equal in both keys and values.
|
||||
*
|
||||
* @param mixed[] $iterable1
|
||||
* @param mixed[] $iterable2
|
||||
* @param iterable<mixed> $iterable1
|
||||
* @param iterable<mixed> $iterable2
|
||||
* @return bool
|
||||
*/
|
||||
public static function sequenceEquals(iterable $iterable1, iterable $iterable2): bool {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// XArrayTest.php
|
||||
// Created: 2021-04-26
|
||||
// Updated: 2024-12-02
|
||||
// Updated: 2025-01-21
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -33,28 +33,24 @@ final class XArrayTest extends TestCase {
|
|||
|
||||
foreach(XArray::extractIterator($array1) as $key => $value) {
|
||||
$this->assertTrue(is_string($key) || is_int($key));
|
||||
$this->assertIsArray($array1);
|
||||
$this->assertArrayHasKey($key, $array1);
|
||||
$this->assertEquals($value, $array1[$key]);
|
||||
}
|
||||
|
||||
foreach(XArray::extractIterator($array2) as $key => $value) {
|
||||
$this->assertTrue(is_string($key) || is_int($key));
|
||||
$this->assertIsArray($array2);
|
||||
$this->assertArrayHasKey($key, $array2);
|
||||
$this->assertEquals($value, $array2[$key]);
|
||||
}
|
||||
|
||||
foreach(XArray::extractIterator($array3) as $key => $value) {
|
||||
$this->assertTrue(is_string($key) || is_int($key));
|
||||
$this->assertIsArray($array3);
|
||||
$this->assertArrayHasKey($key, $array3);
|
||||
$this->assertEquals($value, $array3[$key]);
|
||||
}
|
||||
|
||||
foreach(XArray::extractIterator($array4) as $key => $value) {
|
||||
$this->assertTrue(is_string($key) || is_int($key));
|
||||
$this->assertIsArray($array4);
|
||||
$this->assertArrayHasKey($key, $array4);
|
||||
$this->assertEquals($value, $array4[$key]);
|
||||
}
|
||||
|
@ -128,13 +124,13 @@ final class XArrayTest extends TestCase {
|
|||
$array1 = ['Windows', 'Flashwave', 'Misaka Mikoto', 'Misuzu', 'Index', 'Kasane Teto', 'Some garbage'];
|
||||
$array2 = ['Misaka Mikoto', 'Kasane Teto', 'Some garbage'];
|
||||
|
||||
$this->assertTrue(XArray::sequenceEquals(XArray::where($array1, fn($value) => is_string($value) && strpos($value, ' ') !== false), $array2));
|
||||
$this->assertTrue(XArray::sequenceEquals(XArray::where($array1, fn($value) => strpos($value, ' ') !== false), $array2));
|
||||
}
|
||||
|
||||
public function testFirst(): void {
|
||||
$array = ['Windows', 'Flashwave', 'Misaka Mikoto', 'Misuzu', 'Index', 'Kasane Teto', 'Some garbage'];
|
||||
|
||||
$this->assertEquals(XArray::first($array, fn($value) => is_string($value) && strpos($value, 't') !== false), 'Misaka Mikoto');
|
||||
$this->assertEquals(XArray::first($array, fn($value) => strpos($value, 't') !== false), 'Misaka Mikoto');
|
||||
}
|
||||
|
||||
public function testSelect(): void {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue