worksolutions / php-collections
PHP 语言集合库
Requires
- php: ^7.3 || ~8.0
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^9.5
Suggests
- phpbench/phpbench: Uses only for benchmark purposes
- dev-master
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- v1.0.0
- dev-master-php-8.0
- dev-chunk-reorgonizer-fix
- dev-fix-iterator-behavior
- dev-fix-float-sorted-value
- dev-dev
- dev-obj-functions-improvement
- dev-benchmarking
- dev-one-element-streaming
- dev-map-factory
- dev-bool-expression
- dev-array-strict-list
- dev-parallel-stream
- dev-group-aggregators
- dev-first-element-filter
- dev-doc
This package is auto-updated.
Last update: 2024-09-20 19:09:38 UTC
README
PHP 的集合库。它通过函数式方法方便地处理常见的数据结构。主要数据结构包括:列表、映射、栈、队列、集合。库的一部分是流 API。它提供了一种更函数式的迭代和处理元素的方法。
其他语言版本: 俄语
要求
安装
composer require worksolutions/php-collections
示例
<?php use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; // Getting filtered elements CollectionFactory::from([1, 2, 3]) ->stream() ->filter(Predicates::greaterThan(1)) ->getCollection(); // Collection [2, 3] // Print directory files CollectionFactory::fromIterable(new DirectoryIterator(__DIR__)) ->stream() ->each(static function (SplFileInfo $fileInfo) { echo $fileInfo->getFilename() . "\n"; });
基本概念
该库基于一致的数据处理和转换方法。创建一种转换管道,可以按顺序执行某些步骤。每个步骤只负责自己的一小部分工作。在这种情况下,步骤可以重用,因为它们是原子的。
本质上,该库由几个部分组成,包括
- 数据结构。 每个结构都有其独特的特性,通过接口及其描述和实现来体现。在这种情况下,数据结构的实现可以不同。
- 集合工厂。 集合工厂提供了许多静态方法,用于方便地创建集合。
- 集合流。 流遍历和转换集合,每个转换都会创建一个新的集合实例。
- 遍历和转换函数。 函数集包含在遍历期间易于使用的预准备函数构造器。通过它们的示例,您可以创建和使用更符合您领域特定需求的函数。
数据结构
该库基于最流行的数据结构,可以在不使用任何额外库和类的情况下独立使用。库的所有其他部分都依赖于这些结构,特别是 Collection
接口。所有集合数据结构都包含许多元素,您可以使用它们执行基本操作,如:遍历、转换、聚合等。
集合
集合 - 集合的主要基础接口。除映射(Map)之外的所有数据结构都实现此接口,所有附加功能(工厂、遍历线程)都使用此接口。为了在您的应用程序中保持通用性,建议使用 Collection
接口,但前提是不违反使用结构的初衷。
集合可以使用 foreach
循环进行遍历。
接口方法
- add – 向集合添加项目
- addAll – 向集合添加多个项目
- merge – 合并集合
- clear – 移除集合中的所有元素
- remove – 移除集合项目
- contains – 检查集合中是否存在元素
- equals – 比较两个集合是否等价
- size – 获取集合中的项目数
- isEmpty – 检查集合是否为空
- toArray – 将集合元素转换为数组
- copy – 获取集合的副本
- stream – 获取集合遍历流(Stream)
- 使用foreach循环遍历集合
add - 向集合中添加一个项目
add($element: mixed): bool;
将项目添加到集合的末尾。成功返回true
,失败返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2]); // [1, 2] $collection->add(10); // [1, 2] -> [1, 2, 10];
addAll - 向集合中添加多个项目
addAll($elements: iterable): bool;
将多个项目添加到集合的末尾。成功返回true
,失败返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2]); // [1, 2] $collection->add([10, 11, 12]); // true $collection->toArray(); // [1, 2] -> [1, 2, 10, 11, 12];
merge - 合并集合
merge($collection: Collection): bool;
该方法将当前集合与传入的集合合并。成功返回true
,失败返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2]); // [1, 2] $mergingCollection = CollectionFactory::from([11, 12]); // [11, 12] $collection->merge($mergingCollection); // true $collection->toArray(); // [1, 2, 10, 11, 12];
clear - 移除集合中的所有元素
clear(): void;
该方法移除集合中的所有元素。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2]); // [1, 2] $collection->clear(); // null $collection->toArray(); // [];
remove - 移除集合中的项目
remove($element: mixed): bool;
移除集合中的特定项目。该方法返回删除元素的标志。如果元素不存在,则返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection->remove(2); // true $collection->remove(4); // false $collection->toArray(); // [1, 3];
contains - 检查集合中是否存在元素
contains($element: mixed): bool;
检查特定项目是否存在于集合中。如果元素不存在,则返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection->contains(2); // true $collection->contains(4); // false
equals - 比较两个集合是否相等
equals($collection: Collection): bool;
该方法检查传入的集合是否与当前集合相等,这意味着一个集合的所有元素都包含在另一个集合中,且元素数量相等。如果集合不相等,则返回false
。
use WS\Utils\Collections\HashSet; $set1 = new HashSet([1, 2, 3]); $set2 = new HashSet([3, 2, 1]); $set3 = new HashSet([3, 2]); $set1->equals($set2); // true $set2->equals($set1); // true $set1->equals($set3); // false
size - 获取集合中的项目数量
size(): int;
该方法返回集合中的元素数量。如果集合为空 - 0。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection->size(); // 3 $emptyCollection = CollectionFactory::from([]); $emptyCollection->size(); // false
isEmpty - 检查集合是否为空
isEmpty(): bool;
该方法返回空集合的属性。如果集合中有元素,则返回false
。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection->isEmpty(); // false $emptyCollection = CollectionFactory::from([]); $emptyCollection->isEmpty(); // true
toArray - 将集合元素转换为数组
toArray(): array;
一个由集合元素组成的索引数组方法,元素的顺序取决于内部表示。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection->toArray(); // [1, 2, 3] $emptyCollection = CollectionFactory::from([]); $emptyCollection->toArray(); // []
copy - 获取集合的副本
copy(): Collection;
该方法返回集合的精确副本。集合是可变的。这意味着使用修改方法会修改集合;为确保集合不可变,建议使用副本方法。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $copyOfCollection = $collection->copy(); // Collection $copyOfCollection === $collection; // false
stream - 获取集合遍历流(Stream)
stream(): Stream;
一个实现集合遍历接口的对象(Stream)。集合遍历流是一个非常强大的工具,在大多数情况下您在开发过程中都需要处理它。[更多...](#Collection streams)
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] $collection ->stream() ->each(static function (int $el) {var_export($el);}); // 1 2 3
使用foreach循环遍历集合
集合可以在 * foreach * 循环中进行遍历。集合的迭代顺序取决于特定类的内部实现。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::from([1, 2, 3]); // [1, 2, 3] foreach($collection as $item) { var_export($item); }
列表(ListSequence)
列表是一种数据结构,其中元素的顺序是严格定义的。具有相同元素集合但顺序不同的列表不相等。ListSequence接口扩展了Collection接口。
ListSequence接口扩展接口: Collection
实现ListSequence
接口的类:ArrayList, ImmutableList
接口方法
get - 通过序号获取项目
get($index: int): mixed;
该方法返回索引处的项目。如果索引处不存在元素,则返回null。列表的第一个元素索引为0。
use WS\Utils\Collections\ArrayList; $list = ArrayList::of(1, 2); $list->get(0); // 1 $list->get(1); // 2 $list->get(2); // null
set - 替换列表项目
set($element: mixed, $index: int): mixed;
该方法通过索引替换元素。返回被当前方法替换的元素的值。如果尝试替换一个不存在的元素,将抛出 OutOfRangeException。
use WS\Utils\Collections\ArrayList; $list = ArrayList::of(1, 2); $list->set(3, 0); // 1 $list->set(4, 1); // 2 $list->set(4, 2); // OutOfRangeException
indexOf - 获取元素的序号索引
indexOf($element: mixed): ?int;
该方法返回找到的元素的第一索引。如果列表中没有值,它将返回 null
。
use WS\Utils\Collections\ArrayList; $list = ArrayList::of(1, 2, 1, 3); $list->indexOf(1); // 0 $list->indexOf(2); // 1 $list->indexOf(4); // null
lastIndexOf - 获取最后一个匹配项的序号索引
lastIndexOf($element: mixed): ?int;
该方法返回找到的元素的最后索引。如果列表中没有值,它将返回 null
。
use WS\Utils\Collections\ArrayList; $list = ArrayList::of(1, 2, 1, 3); $list->indexOf(1); // 2 $list->indexOf(2); // 1 $list->indexOf(3); // null
removeAt - 通过索引删除元素
removeAt(int $index): mixed;
该方法通过索引删除元素,删除索引后的元素向起始方向移动一个位置。返回被删除项的值。如果索引不存在,它将返回 null
。
use WS\Utils\Collections\ArrayList; $list = ArrayList::of(1, 2, 1, 3); $list->removeAt(1); // 2 $list->toArray(); // [1, 1, 3]
集合
该集合只包含唯一元素,元素的顺序可以是任意的。也就是说,使用 add
方法添加元素并不保证它在迭代期间在其他元素中的最后位置,并且如果存在具有相同值的元素,后者将不会被添加到集合中。
唯一性由值确定,对于对象,则由特定对象的唯一性确定,或者,如果对象实现了 HashCodeAware
接口,则由调用 getHashCode (): string;
返回的结果的唯一性确定。
Set
接口扩展了基接口: Collection
实现 Set
接口的类: HashSet
队列
类似于队列的数据结构方便于按到达顺序对数据进行顺序处理。它提供了方便的添加和消费项的方法。首先进入队列的第一个元素将是第一个离开的元素。
Queue
接口扩展了基接口: Collection
实现 Queue
接口的类: ArrayQueue
接口方法
offer - 将项目插入到队列中
offer($element): bool;
该方法将项目添加到队列的末尾。如果没有添加项目,则返回 false
,可能是在有限队列的情况下。
use WS\Utils\Collections\ArrayQueue; $queue = ArrayQueue::of(1, 2); $queue->offer(3); // [1, 2, 3] $queue->peek(); // 3
poll - 从队列中获取项目并删除它
poll(): mixed;
该方法返回一个元素并从队列的头部删除它。如果没有项目在队列中,将抛出 RuntimeException
。
use WS\Utils\Collections\ArrayQueue; $queue = ArrayQueue::of(1, 2); $queue->peek(); // 2 $queue->poll(); // [1] $queue->peek(); // 1
peek - 获取项目而不从队列中删除它
poll(): mixed;
该方法返回一个元素。在这种情况下,队列不会改变,元素保持在原位。如果没有项目在队列中,将抛出 RuntimeException
。
use WS\Utils\Collections\ArrayQueue; $queue = ArrayQueue::of(1, 2, 3); $queue->peek(); // 2 $queue->size(); // 3
栈
栈是一种数据结构,其逻辑与队列的逻辑相反。栈顶的第一个项目将是第一个进入的,也将被弹出。
Stack
接口扩展了基接口: Collection
实现 Stack
接口的类: ArrayStack
接口方法
push - 推入项目
push($element: mixed): bool;
该方法将项目推送到栈顶。如果没有添加元素,则返回 false
,可能是在受限的情况下。
use WS\Utils\Collections\ArrayStack; $queue = ArrayStack::of(1, 2); $queue->push(3); // [1, 2, 3] $queue->peek(); // 3
pop - 取出最后添加的项目
pop(): mixed;
该方法从栈顶返回项目。栈顶是先于接收到的项目添加的元素。如果没有元素在栈上,将抛出 RuntimeException
。
use WS\Utils\Collections\ArrayStack; $queue = ArrayStack::of(1, 2, 3); // [1, 2, 3] $queue->pop(); // 3 $queue->pop(); // 2 $queue->push(4); // [1, 4] $queue->pop(); // 4 $queue->peek(); // 1
peek - 获取最后添加的项目而不修改栈
peek(): mixed;
该方法返回栈顶的项。如果没有元素在栈中,将抛出 RuntimeException
异常。
use WS\Utils\Collections\ArrayStack; $queue = ArrayStack::of(1, 2, 3); // [1, 2, 3] $queue->pop(); // 3 $queue->peek(); // 3 $queue->peek(); // 3 $queue->pop(); // 2 $queue->pop(); // 1 $queue->peek(); // RuntimeException
映射
Map 接口表示一种映射,换句话说是一个字典,其中每个元素代表一个键值对。Map 键在值上是唯一的,如果它们是对象,则通过对象的引用唯一性或通过实现 HashCodeAware
接口并调用 getHashCode (): string;
方法的结果唯一性来达到。
Map
接口扩展了基本接口: IteratorAggregate
实现 Stack
接口的类:HashMap
接口方法
- put – 添加 key/value 对
- get – 通过键获取对的值
- keys – 获取地图键的集合
- values – 获取地图值的集合
- remove – 通过键删除对
- containsKey – 标记键对的存在
- containsValue – 标记通过值对的存在
- size – 卡片中对的数目
- stream - 获取带有键值对集合的遍历流(Stream)
- 在 foreach 循环中遍历地图
put - 添加键值对
put($key: mixed, $value: mixed): bool;
该方法向结构对象添加键/值对。如果没有添加项,则返回 false,可能是由于限制。键和值可以是标量类型、数组或对象的数据。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); foreach ($map as $k => $v) { var_dump($k); // one | two var_dump($v); // 1 | 2 }
get - 通过键获取对的值
get($key): mixed;
该方法通过键 key
返回对的值。如果没有值,它将返回 null
。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->get('one'); // 1 $map->get('three'); // null
keys - 获取地图键的集合
keys(): Collection<mixed>;
该方法返回一个包含所有地图键的集合。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); foreach ($map->keys() as $k) { var_dump($k); // one | two }
values - 获取地图值的集合
values(): Collection<mixed>;
该方法返回一个包含所有地图对值的集合。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); foreach ($map->keys() as $v) { var_dump($v); // 1 | 2 }
remove - 通过键删除对
remove($key: mixed): bool;
该方法通过键 key
从地图中删除一个对。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->remove('one'); foreach ($map->keys() as $v) { var_dump($v); // 2 }
containsKey - 标记键对的存在
containsKey($key: mixed): bool;
该方法返回一个表示存在具有键 key
的对的指示。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->containsKey('one'); // true
containsValue - 标记通过值对的存在
containsValue($value: mixed): bool;
该方法返回一个表示存在具有值 value
的对的指示。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->containsValue(1); // true $map->containsValue(3); // false
size - 卡片中对的数目
size(): int;
该方法返回对的数目。
use WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->size(); // 2 $emptyMap = new HashMap(); $map->size(); // 0
stream - 获取带有键值对对的遍历流(Stream)
stream(): Stream;
方法返回 Stream 接口的对象。内部集合元素是键/值对。
use \WS\Utils\Collections\HashMap; use \WS\Utils\Collections\MapEntry; $map = new HashMap(); $map->put('one', 1); $map->put('two', 2); $map->put('tree', 3); $map->stream()->each(static function (MapEntry $mapEntry) { var_export($mapEntry->getKey()); // 'one', 'two', 'three' var_export($mapEntry->getKey()); // 1 , 2 , 3 });
在 foreach 循环中遍历地图
Map 接口的对象可以在 foreach 循环中迭代。在这种情况下,键和值将按顺序传递。键可以是任何类型,但不能是数组。
use \WS\Utils\Collections\HashMap; $map = new HashMap(); $map->put(new SplObjectStorage(), 1); $map->put(null, 2); $map->put(false, 3); $map->put(true, 4); $map->put(0, 5); foreach($map as $key => $value) { var_export($key); // object of SplObjectStorage class| null| false| true| 0 var_export($value); // 1 | 2 | 3 | 4 | 5 }
集合工厂
CollectionFactory
工厂允许您在不使用特定实现构造函数的情况下创建集合对象,或者也有其他方便的方法来创建集合对象。目前,库的主要结构是 ArrayList
,该工厂通过静态方法生成。
示例
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::numbers(10) ->stream() ->each(Consumers::dump()); // dumps int(0), int(1), ...
集合创建工厂方法
- CollectionFactory::from – 从元素数组生成集合
- CollectionFactory::fromIterable – 使用任何可迭代表生成集合
- CollectionFactory::numbers – 生成整数序列集合
- CollectionFactory::generate – 使用生成器生成集合
- MapFactory::fromIterable – 从任何迭代值生成地图
- MapFactory::assoc – 从关联数组生成地图
CollectionFactory::from - 从元素数组生成集合
from($values: array): Collection
该方法创建一个由传入数组元素组成的集合。
目前,集合实现是 ArrayList
,未来具体实现可能会改变,调用此方法时,应仅依赖于 Collection
接口。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::from([1 ,2, 3]) ->stream() ->each(Consumers::dump()); // dumps int(1), int(2), int(3)
CollectionFactory::fromIterable - 使用任何可迭代对象生成集合
fromIterable($iterable: iterable): Collection
该方法创建一个集合,其元素由传递的迭代器的元素组成。
目前,集合实现是 ArrayList
,未来具体实现可能会改变,调用此方法时,应仅依赖于 Collection
接口。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; use WS\Utils\Collections\Functions\Converters; CollectionFactory::fromIterable(new DirectoryIterator(__DIR__)) ->stream() ->map(Converters::toPropertyValue('filename')) ->each(Consumers::dump()); // Dumps strings with filenames
_CollectionFactory::numbers - 生成整数序列集合
numbers($from: int, $to: ?int): Collection
该方法创建一个集合,其元素由整数序列 [$ from .. $ to]
组成。如果未传递 $ to
参数,将返回 [0 .. $ from]
集合。
目前,集合的实现是 ArrayList
,将来具体实现可能会更改,在调用此方法时,应仅依赖于 Collection
接口。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::numbers(10, 15) ->stream() ->each(Consumers::dump()); // Dumps [10, 11, 12, 13, 14, 15]
CollectionFactory::generate - 使用生成器生成集合
generate($times: int, $generator: ?callable): Collection
该方法创建一个大小为 $ times
的集合,其元素由调用生成器 $ generator
的结果值组成。
目前,集合的实现是 ArrayList
,将来具体实现可能会更改,在调用此方法时,应仅依赖于 Collection
接口。如果您需要一个特定类型的集合实例,您需要使用实现构造函数或它们的静态方法。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::generate(3, static function () { return random_int(0, 10); }) ->stream() ->each(Consumers::dump()); // Dumps for example [9, 7, 2]
MapFactory::fromIterable - 从任何迭代值生成映射
MapFactory::fromIterable($iterable: iterable): Map
方法从任何迭代对象创建映射对象。
use WS\Utils\Collections\MapFactory; MapFactory::fromIterable(['a' => 1, 'b' => 2]) ->keys() // ['a', 'b'] ;
MapFactory::assoc - 从关联数组生成映射
MapFactory::assoc(array $assocArray): Map
方法从关联数组创建映射对象。
use WS\Utils\Collections\MapFactory; MapFactory::assoc(['a' => 1, 'b' => 2]) ->keys() // ['a', 'b'] ;
集合流
为了更方便地遍历和转换集合,必须使用流。基本上,所有计算都应通过流完成。要获取流,需要调用集合方法 Collection::stream ()
。
通过执行函数处理集合,这些函数的接口必须与遍历/转换目的相匹配。有六个接口
- 断言。用于过滤元素
filter
,如果对该元素的断言调用返回布尔正值,则元素保留在流集合中。库中已经包含了一些准备好的断言。 - 转换器。此类函数用于转换
map
流集合。转换器必须返回一个值,该值通过某些属性与集合的传递元素相对应。库中已经包含了一些 准备好的转换器。 - 消费者。消费者函数不修改流集合,但用于遍历
each
集合。将为集合的每个元素调用传递的函数;函数的结果不予考虑。库中已经包含了一些 准备好的消费者。 - 比较器。比较器参与排序项目以确定两个值的排序顺序。如果第一个参数分别小于、等于或大于第二个参数,则必须返回一个小于、等于或大于零的整数。php.net usort。库中已经包含了一些 准备好的比较函数。
- 重组器。转换函数将一个集合转换成另一个
reorganize
而不改变流对象。转换在需要根据原始集合中的所有信息获取最终集合,而不仅仅是将一个元素转换成另一个元素时是必要的。例如,随机排列元素或形成块的方法。库中已经包含了一些 准备好的重组器。 - 收集器。使用 collect 方法将数据收集功能应用于流,实际上,执行此组函数的结果将是执行流的结果。collect 方法是终端的,即调用此方法将终止流。
所有流都属于 Stream
接口,这意味着接口的描述保证了其正确执行,无论具体实现如何,异常只是流行为的特殊情况(when
)。
Stream 保证在每个修改方法之后,getCollection
方法将返回不同的对象实例,这是一种从安全角度维护转换期间不可变性的安全方法。
Stream 接口方法
- each – 遍历集合元素
- walk – 有限遍历集合元素
- filter – 过滤集合元素
- map – 转换流集合元素
- reorganize – 流集合转换
- collect – 收集数据
- sort – 对集合中的项目进行排序
- sortBy – 按值排序集合元素
- sortDesc – 按逆序排序集合元素
- sortByDesc – 按值逆序排序集合元素
- reduce – 将集合归约为一个单一值
- when – 通过条件约束流修改
- always – 移除流修改约束
- getCollection – 获取流集合
- allMatch – 通过谓词完全匹配所有元素
- anyMatch – 通过谓词部分匹配所有元素
- findAny – 获取任意集合项
- findFirst – 获取集合中的第一个项
- findLast – 获取集合中的最后一个项
- min – 获取集合的最小元素
- max – 获取集合中的最大项
- reverse – 反转集合的元素
- limit – 将集合缩小到指定的大小
each - 遍历集合元素
each($consumer: <fn($element: mixed, $index: int): void>): Stream;
该方法将消费者函数应用于流集合中的每个元素。函数的结果不考虑。调用 each
方法不会改变流中的集合,但同时也访问集合中的每个项目。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::numbers(10) ->stream() ->each(Consumers::dump()) // dumps each element ->each(static function ($el) { // prints strings 0, 1, 2, 3 echo $el."\n"; }) ;
walk - 有限遍历集合元素
walk($consumer: <fn($element: mixed, $index: int): false|void>, $limit: ?int): Stream;
该方法将消费者函数应用于流集合中的每个元素,就像在 each
方法中一样。函数的结果不考虑。调用 each
方法不会改变流中的集合,但同时也访问集合中的每个项目。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::numbers(10) ->stream() ->walk(Consumers::dump(), 5) // dumps only first 5 elements: 0, 1, 2, 3, 4 ->walk(static function ($el) { // prints strings 0, 1, 2, 3. Method will be called only 5 times if ($el === 4) { return false; } echo $el."\n"; }) ;
filter - 过滤集合元素
filter($predicate: <fn($element: mixed): bool>): Stream;
该方法将谓词函数应用于流集合中的每个元素。如果从元素到谓词的调用返回负结果(false, 0, '', []
),则该元素将被排除在集合之外。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() ->filter(static function (int $el): bool { return $el % 2 === 0; }) ->getCollection() // returns only first 5 elements: 0, 2, 4, 6, 8 ;
map - 转换流集合元素
map($converter: <fn($element: mixed): mixed>): Stream;
该方法将流应用于集合中的每个元素,并用函数执行的结果替换传递给集合的元素。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() ->map(static function (int $el): int { return $el * 10; }) ->getCollection() // returns 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 ;
reorganize - 流集合转换
reorganize($reorganizer: <fn($collection: Collection): Collection>): Stream;
该方法将 $reorganizer
应用于内部集合,然后用方法调用的结果替换内部集合。当需要进行基于完整集合数据的转换时需要。
use WS\Utils\Collections\ArrayStack; use WS\Utils\Collections\Collection; use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() // reverse collection ->reorganize(static function (Collection $collection): Collection { $stack = new ArrayStack(); foreach ($collection as $item) { $stack->push($item); } $reversed = CollectionFactory::empty(); while (!$stack->isEmpty()) { $reversed->add($stack->pop()); } return $reversed; }) ->getCollection() ;
collect - 收集数据
collect($collector: <fn ($collection: Collection): mixed>): mixed;
该方法将收集器函数应用于内部集合并返回结果。当需要使用流对集合执行最终操作时需要。终端方法。
use WS\Utils\Collections\Collection; use WS\Utils\Collections\CollectionFactory; $sumOfElements = CollectionFactory::numbers(10) ->stream() // get sum of collection elements ->collect(static function (Collection $collection): int { $res = 0; foreach ($collection as $item) { $res += $item; } return $res; }) ;
sort - 对集合中的项目进行排序
sort($comparator: <fn($a: mixed, $b: mixed): int>): Stream;
该方法根据$comparator
的工作对项目进行排序。比较器确定两个值的排序顺序。如果第一个参数分别小于、等于或大于第二个参数,必须返回一个小于、等于或大于零的整数。php.net usort
use WS\Utils\Collections\CollectionFactory; $sortedCollection = CollectionFactory::generate(10, static function (): int { return random_int(0, 100); }) ->stream() // get sorted collection ->sort(static function (int $a, int $b): int { return $a <=> $b; }) ->getCollection() ;
sortDesc - 以相反顺序对集合中的元素进行排序
sortDesc($comparator: <fn($a: mixed, $b: mixed): int>): Stream;
该方法根据$ comparator的工作对元素进行排序,但与常规排序函数不同,元素将以降序排列。编译器确定两个值的排序顺序。如果第一个参数分别小于、等于或大于第二个参数,必须返回一个小于、等于或大于零的整数。php.net usort
use WS\Utils\Collections\CollectionFactory; $sortedDescendentCollection = CollectionFactory::generate(10, static function (): int { return random_int(0, 100); }) ->stream() // get sorted collection in the reverse order ->sortDesc(static function (int $a, int $b): int { return $a <=> $b; }) ->getCollection() ;
sortBy - 按值对集合项目进行排序
sortBy($extractor: <fn($el: mixed): scalar>): Stream;
该方法根据每个元素的接收到的$ extractor函数的值对元素进行排序。函数必须返回一个标量值,以启用独立优化排序。按值降序排序的方法sortByDesc
类似。
use WS\Utils\Collections\CollectionFactory; class Container { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $sortedCollection = CollectionFactory::generate(10, static function (): Container { return new Container(random_int(0, 100)); }) ->stream() // get sorted collection ->sortBy(static function (Container $container): int { return $container->getValue(); }) ->getCollection() ;
reduce - 将集合缩减为单个值
reduce($accumulator: <fn($el: mixed, $carry: mixed): mixed>): mixed;
该方法将集合转换为单个值。函数接收可迭代元素的值$el
和调用同一函数的先前元素的返回结果 $carry
。在第一次迭代中,$carry === null
。终端方法。
use WS\Utils\Collections\CollectionFactory; $sumOfCollection = CollectionFactory::numbers(10) ->stream() // get sum of collection elements ->reduce(static function (int $el, ?int $carry = null): int { return $carry + $el; }) ;
when - 通过条件约束流修改
when($condition: bool): Stream;
如果$condition
不满足,则限制修改,并且所有修改和绕过方法都不会被调用。相反的方法是[always
](#移除流修改约束)。
锁定方法
use WS\Utils\Collections\Collection; use WS\Utils\Collections\CollectionFactory; $randomElementSizeCollection = CollectionFactory::numbers(random_int(0, 20)); $onlyTenElements = $randomElementSizeCollection ->stream() // get collection elements only 10 items ->when($randomElementSizeCollection->size() > 10) ->limit(10) ->when($randomElementSizeCollection->size() < 10) ->reorganize(static function (Collection $collection) { for ($i = $collection->size(); $i < 10; $i++ ) { $collection->add($i); } return $collection; }) ;
always - 移除流修改约束
always(): Stream;
如果流之前通过[when
条件](#通过条件约束流修改)阻止了修改,则always
方法取消对修改方法进一步调用的限制。
use WS\Utils\Collections\CollectionFactory; $collection = CollectionFactory::numbers(20); $onlyTenElements = $collection ->stream() // get collection elements only 10 items ->when($collection->size() > 5) ->limit(5) ->always() ->map(static function (int $el): int { return $el * 10; }) ->getCollection() // [0, 10, 20, 30, 40] ;
getCollection - 获取流集合
getCollection(): Collection;
该方法根据之前执行的操作返回集合。即使对流调用转换方法,结果集合也将保持不变。终端方法。
use WS\Utils\Collections\CollectionFactory; $stream = CollectionFactory::numbers(10) ->stream(); $collection1 = $stream ->map(static function (int $el): int{ return $el * 10; }) ->getCollection() ; $collection2 = $stream ->filter(static function (int $el): bool { return $el > 50; }) ->getCollection() ; $collection1->size() === $collection2->size(); // false $collection2->toArray(); // [60, 70, 80, 90]
allMatch - 通过谓词对所有元素进行完整匹配
allMatch($predicate: <fn($el: mixed): bool>): bool;
如果对集合的元素调用 $predicate
的所有调用都为真(true
),则方法将返回true
。终端方法。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() ->allMatch(static function (int $el): bool { return $el >= 1; }) // false, 0 is less than 1 ;
anyMatch- 通过谓词对所有元素进行部分匹配
anyMatch(callable $predicate): bool;
如果对集合的元素进行至少一次调用 $ predicate
为真(true
),则方法将返回true
。终端方法。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() ->anyMatch(static function (int $el): bool { return $el > 0; }) // true, [1, 2, 3, 4, 5, 6, 7, 8, 9] are grate than 0 ;
findAny - 获取任意集合项目
findAny(): mixed;
该方法返回集合的任意元素,如果集合为空,则返回null
。不保证项是随机选择的。终端方法。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) ->stream() ->findAny() // for example - 5 ;
findFirst- 获取集合中的第一个项目
findFirst(): mixed;
该方法将返回集合的第一个元素,如果集合为空,则返回null
。终端方法。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->findFirst() // 0 ;
findLast- 获取集合中的最后一个项目
findLast(): mixed;
该方法将返回集合的最后一个元素,如果集合为空,则返回null
。终端方法。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->findLast() // 9 ;
min - 获取集合的最小元素
min($comparator: <fn($a: mixed, $b: mixed): int>): mixed;
该方法将返回比较函数比较下的集合中最小的项,如果集合为空,则返回null
。终端方法。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->reorganize(Reorganizers::shuffle()) ->min(static function (int $a, int $b): int { return $a <=> $b; }) // 0 ;
max - 获取集合中的最大项目
max($comparator: <fn($a: mixed, $b: mixed): int>): mixed;
该方法将返回比较函数比较下的集合中最大的项,如果集合为空,则返回null
。终端方法。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->reorganize(Reorganizers::shuffle()) ->max(static function (int $a, int $b): int { return $a <=> $b; }) // 9 ;
reverse - 反转集合的元素
reverse(): Stream;
该方法将元素的顺序转换为反转序列。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->reverse() ->getCollection() // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] ;
limit - 将集合缩小到指定大小
limit(int $size): Stream;
此方法将元素数量减少到指定大小。如果元素数量已经小于在 $size
限制中指定的数量,元素数量将保持不变。
use WS\Utils\Collections\CollectionFactory; CollectionFactory::numbers(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->stream() ->reverse() ->getCollection() // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] ;
遍历和转换函数
库包含大多数流行函数的构造函数,这些函数使用预准备的参数来启动遍历和转换线程的工作。
例如
use \WS\Utils\Collections\Functions\Predicates; $equal10Predicate = Predicates::equal(10); $equal10Predicate(11); // false $equal10Predicate(10); // true
调用函数构造函数 Predicates::equal(10)
将返回一个比较输入参数与值 10 的函数。
库中使用的函数分为以下类型
每种函数类型都必须有对应的接口,以便在特定的流方法中使用。
谓词
[↑ 遍历和转换函数] 一组用于过滤流集合的函数构造函数。所有方法返回具有以下接口的初始化函数: <Fn($el: mixed): bool>
。谓词还允许您使用对象属性。例如,对象的 myProperty
属性表示对象中存在名为 myProperty
的公共属性,或者存在名为 getMyProperty
的 getter
方法。
- lock – 锁定
- notResistance – 传递所有值
- notNull – 检查值的空性
- eachEven – 传递偶数调用项
- nth – 传递指定元素
- equal – 等价检查
- lockDuplicated – 锁定重复值
- lessThan – 检查值是否小于
- lessOrEqual – 检查值是否小于或等于
- greaterThan – 检查值是否大于
- greaterOrEqual – 检查值是否大于或等于
- not – 检查值是否不等于
- in – 检查值是否在值组中
- notIn – 检查值是否不在值组中
- where – 检查对象属性是否等价
- whereNot – 检查对象属性是否不等价
- whereIn – 检查对象属性是否在值组中
- whereNotIn – 检查对象属性是否不在值组中
- whereGreaterThan – 检查对象属性是否大于
- whereLessThan – 检查对象属性是否小于
- wheregGreaterOrEqual – 检查对象属性是否大于或等于
- whereLessOrEqual – 检查对象属性是否小于或等于
lock – 锁定
lock(): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,对于任何一组输入数据,将返回 false
。本质上,该方法生成一个流阻塞函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; $lockFunction = Predicates::lock(); CollectionFactory::numbers(1, 10) ->stream() ->filter($lockFunction) ->getCollection() ->isEmpty() // true ;
notResistance – 传递所有值
notResistance(): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,对于任何一组输入数据,将返回 true
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; $passFunction = Predicates::notResistance(); CollectionFactory::numbers(1, 10) ->stream() ->filter($passFunction) ->getCollection() ->size() // 10 ;
notNull – 检查值的空性
notNull(): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,对于任何一组输入数据,将返回 true
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; $notNullPassFunction = Predicates::notNull(); CollectionFactory::from([1, 10, null]) ->stream() ->filter($notNullPassFunction) ->getCollection() ->size() // 2 ;
eachEven - 传递偶数调用项
eachEven(): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,在每次偶数调用时将返回 true
,相应地,在其他情况下返回 false
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; $evenPassFunction = Predicates::eachEven(); CollectionFactory::from([1, 2, 3, 4, null, false]) ->stream() ->filter($evenPassFunction) ->getCollection() ->toArray() // 2, 4, false ;
nth – 传递指定元素
nth($number: int): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,每次 $number
调用将返回 true
,相应地,在其他情况下返回 false
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; $thirdPassFunction = Predicates::nth(3); CollectionFactory::from([1, 2, 3, 4, null, false]) ->stream() ->filter($thirdPassFunction) ->getCollection() ->toArray() // 3, false ;
equal – 等价检查
equal($value: mixed): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,当集合项与 $value
的值匹配时返回 true
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, false]) ->stream() ->filter(Predicates::equal(3)) ->findFirst() // 3 ;
lockDuplicated – 锁定重复值
lockDuplicated(): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个函数,仅对具有唯一成员的调用返回 true
。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([3, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::lockDuplicated()) ->getCollection() ->toArray() // [3, 2, 4, null] ;
小于 – 检查值是否符合“小于”条件
lessThan($value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较元素与值 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::lessThan(4)) ->getCollection() ->toArray() // [1, 2, 3, null, 3] ;
小于等于 – 检查值是否符合“小于等于”条件
lessOrEqual($value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较元素与值 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::lessOrEqual(2)) ->getCollection() ->toArray() // [1, 2, null] ;
大于 – 检查值是否符合“大于”条件
greaterThan($value: scalar): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于比较元素与值 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::greaterThan(2)) ->getCollection() ->toArray() // [3, 4, 3] ;
大于等于 – 检查值是否符合“大于等于”条件
greaterOrEqual($value: scalar): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于比较元素与值 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::greaterOrEqual(2)) ->getCollection() ->toArray() // [2, 3, 4, 3] ;
非 – 检查值是否符合不等式
not($value: mixed): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查集合元素与值 $value
不等式的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::not(3)) ->getCollection() ->toArray() // [1, 2, 4, null] ;
在...中 – 检查值是否属于一组值
in($values: array): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查元素是否在数组 $values
中的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::in([null, 3])) ->getCollection() ->toArray() // [3, null, 3] ;
不在...中 – 检查值是否不属于一组值
notIn($values: array): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查元素在集合 $values
中不存在的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; CollectionFactory::from([1, 2, 3, 4, null, 3]) ->stream() ->filter(Predicates::notIn([null, 3])) ->getCollection() ->toArray() // [1, 2, 4] ;
where – 检查对象属性是否等同于某个值
where($property: string, $value: mixed): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查元素对象的属性是否等于 $value
的值的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::where('value', 0)) ->getCollection() ->isEmpty() // false ;
whereNot – 检查对象属性是否不等于某个值
whereNot($property: string, $value: mixed): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查元素对象的属性是否不等于 $value
的值的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereNot('value', 0)) ->getCollection() ->toArray() // [#1, #2, #3, #4] ;
whereIn – 检查对象属性是否属于一组值
whereIn($property: string, $values: array): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查对象属性的值是否在集合 $values
中的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereIn('value', [0, 4, 9])) ->getCollection() ->toArray() // [#0, #4] ;
whereNotIn – 检查对象属性是否不属于一组值
whereNotIn($property: string, $values: array): Closure; \\ <Fn($el: mixed): bool>
该方法启动一个用于检查对象属性的值在集合 $values
中不存在的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereIn('value', [0, 4, 9])) ->getCollection() ->toArray() // [#0, #4] ;
whereGreaterThan – 检查对象属性是否符合“大于”条件
whereGreaterThan($property: string, $value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较对象属性的值与 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereGreaterThan('value', 3)) ->getCollection() ->toArray() // [#4] ;
whereLessThan – 检查对象属性是否符合“小于”条件
whereLessThan($property: string, $value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较对象属性的值与 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereLessThan('value', 3)) ->getCollection() ->toArray() // [#0, #1, #2] ;
whereGreaterOrEqual – 检查对象属性是否符合“大于等于”条件
whereGreaterOrEqual($property: string, $value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较对象属性的值与 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereGreaterOrEqual('value', 3)) ->getCollection() ->toArray() // [#3, #4] ;
whereLessOrEqual – 检查对象属性是否符合“小于等于”条件
whereLessOrEqual($property: string, $value: scalar): Closure; \\ <Fn($el: scalar): bool>
该方法启动一个用于比较对象属性的值与 $value
的函数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Predicates; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } $c = 0; CollectionFactory::generate(5, static function () use (& $c) { return new ValueObject($c++); }) ->stream() ->filter(Predicates::whereLessOrEqual('value', 3)) ->getCollection() ->toArray() // [#1, #2, #3] ;
比较器
比较函数构造器组。当使用排序方法排列元素时需要比较函数。生成的排序函数具有接口 <Fn($a: mixed, $b: mixed): int>
,与 [https://php.ac.cn/manual/ru/function.usort] 具有相同的逻辑。
scalarComparator 标量值比较
scalarComparator(): Closure; \\ <Fn($a: scalar, $b: scalar): int>
该方法启动一个用于比较两个值的函数。比较函数返回一个整数,该整数小于、等于或大于零,分别表示第一个参数分别小于、等于或大于第二个参数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Comparators; CollectionFactory::generate(5, static function (): int { return random_int(0, 10); }) ->stream() ->sort(Comparators::scalarComparator()) ->getCollection() ->toArray() // sorted value, for example [2, 3, 6, 7, 8] ;
objectPropertyComparator – 对象属性比较
objectPropertyComparator($property: string): Closure; \\ <Fn($a: object, $b: object): int>
该方法启动一个用于比较两个对象属性值的函数。比较函数返回一个整数,该整数小于、等于或大于零,分别表示第一个参数分别小于、等于或大于第二个参数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Comparators; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } CollectionFactory::generate(5, static function () { return new ValueObject(random_int(0, 10)); }) ->stream() ->sort(Comparators::objectPropertyComparator('value')) ->getCollection() ->toArray() // sorted ValueObject objects, for example [#2, #3, #6, #7, #8] ;
callbackComparator – 定义一个用于比较值的函数
callbackComparator($fun: <Fn($value: mixed): scalar>): Closure; \\ <Fn($a: mixed, $b: mixed): int>
该方法启动一个根据 $fun
函数处理值来比较两个值的函数。比较函数返回一个整数,该整数小于、等于或大于零,分别表示第一个参数分别小于、等于或大于第二个参数。
use WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Comparators; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } CollectionFactory::generate(5, static function () { return new ValueObject(random_int(0, 10)); }) ->stream() ->sort(Comparators::callbackComparator(static function (ValueObject $valueObject) { return $valueObject->getValue(); })) ->getCollection() ->toArray() // sorted ValueObject objects, for example [#2, #3, #6, #7, #8] ;
转换器
一组转换元素函数的构造器。转换函数的结果是 <Fn($obj: mixed): mixed>
。
toPropertyValue 将集合中的每个项目转换为属性值
toPropertyValue($property: string): Closure; \\ <Fn($obj: object): mixed>
该方法创建一个函数,该函数返回对象属性的值。
use WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Converters; class ValueObject { private $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; } } CollectionFactory::generate(5, static function (int $index): ValueObject { return new ValueObject($index); }) ->stream() ->map(Converters::toPropertyValue('value')) ->getCollection() ->toArray() // [0, 1, 2, 3, 4 ] ;
toProperties 将集合中的每个项目转换为关联数组
toProperties($names: array<string>): Closure; \\ <Fn($obj: object): array>
该方法启动一个函数,该函数返回一个对象属性的关联数组,其键为属性名称。
use WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Converters; class Person { private $name; private $surname; public function __construct(string $name, string $surname) { $this->name = $name; $this->surname = $surname; } public function getName(): string { return $this->name; } public function getSurname(): string { return $this->surname; } } CollectionFactory::generate(1, static function (): Person { return new Person('Ivan', 'Ivanov'); }) ->stream() ->map(Converters::toProperties(['name', 'surname'])) ->getCollection() ->toArray() // [['name' => 'Ivan', 'surname' => 'Ivanov']] ;
重新组织者
流转换方法构造函数。与元素转换函数不同,其中原始集合的每个元素对应于新集合的元素,给定第一个元素的位置,流转换方法创建一个具有任意元素数量的派生新集合。
shuffle - 改变集合项的顺序
shuffle(): Closure; \\ <Fn(): Collection>
该方法启动一个函数,该函数返回一个新集合,其中项目按随机顺序排列。
use \WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::numbers(5) ->stream() ->reorganize(Reorganizers::shuffle()) ->getCollection() ->toArray() // for example [0, 3, 1, 2, 4] ;
random - 获取集合的随机元素
random($count = 1: int): Closure; \\ <Fn(): Collection>
该方法启动一个函数,该函数返回一个新集合,其中包含原始集合中随机边界集的元素。
use \WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::numbers(5) ->stream() ->reorganize(Reorganizers::random(2)) ->getCollection() ->toArray() // for example [0, 3] ;
chunk - 将其分割成指定大小的多个集合
chunk($size: int): Closure; \\ <Fn(): Collection>
该方法启动一个函数,该函数返回一个集合,其元素数量小于或等于 $size
。
use \WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::numbers(10) ->stream() ->reorganize(Reorganizers::chunk(2)) ->getCollection() ->toArray() // for example [[0, 1], [2, 3], ...] ;
collapse - 获取没有额外嵌套级别的集合
collapse(): Closure; \\ <Fn(): Collection>
该方法启动一个函数,该函数返回一个没有嵌套容器的集合。在此上下文中,容器是可迭代的数据库结构。
use \WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Reorganizers; CollectionFactory::generate(3, static function (int $i): array { return [$i*2, $i*2 + 1]; }) // [[0, 1], [2, 3], [4, 5]] ->stream() ->reorganize(Reorganizers::collapse()) ->getCollection() ->toArray() // for example [0, 1, 2, 3, 4, 5] ;
消费者
消费者函数构造函数。包含一个打印元素值的函数。基本上,每个消费者函数都是在项目源代码中单独开发的。
dump - 列出集合项的值
dump(): Closure; \\ <Fn(): Collection>
该方法启动一个函数,该函数将传递的值打印到输出流。
use \WS\Utils\Collections\CollectionFactory; use WS\Utils\Collections\Functions\Consumers; CollectionFactory::numbers(5) ->stream() ->each(Consumers::dump()) // dumps each element of collection ;
聚合
by
$group = Group::by($fieldName): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 25], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'taxi', 'type' => 'transport', 'price' => 70], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 20], ]; $result = CollectionFactory::from($items) ->stream() ->collect(Group::by('type')) ; /* Result -> [ 'groceries' => new \WS\Utils\Collections\ArrayList([ ['name' => 'potato', 'type' => 'groceries', 'price' => 25], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ]), 'transport' => new \WS\Utils\Collections\ArrayList([ ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'taxi', 'type' => 'transport', 'price' => 70], ]), 'entertainment' => new \WS\Utils\Collections\ArrayList([ ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 20], ]), ]; */
addToSet
Group::addToSet($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 25], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'taxi', 'type' => 'transport', 'price' => 70], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 20], ]; $aggregation = Group::by('type')->addToSet('name', 'list'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['list' => ['potato', 'milk']], 'transport' => ['list' => ['taxi']], 'entertainment' => ['list' => ['cinema']], ]; */
avg
Group::avg($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'taxi', 'type' => 'transport', 'price' => 50], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->avg('price', 'avg'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['avg' => 40], 'transport' => ['avg' => 75], 'entertainment' => ['avg' => 30], ]; */
count
Group::count($destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'tea', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->count('total'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['total' => 3], 'transport' => ['total' => 1], 'entertainment' => ['total' => 2], ]; */
first
Group::first($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->first('name', 'item'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['item' => 'potato'], 'transport' => ['item' => 'taxi'], 'entertainment' => ['item' => 'Knicks game'], ]; */
last
Group::last($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->last('name', 'item'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['item' => 'milk'], 'transport' => ['item' => 'airplane'], 'entertainment' => ['item' => 'cinema'], ]; */
max
Group::max($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->max('price', 'max'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['max' => 50], 'transport' => ['max' => 100], 'entertainment' => ['max' => 300], ]; */
min
Group::min($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->min('price', 'min'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['min' => 30], 'transport' => ['min' => 50], 'entertainment' => ['min' => 30], ]; */
sum
Group::sum($sourceKey, $destKey): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->sum('price', 'spent'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['spent' => 80], 'transport' => ['spent' => 150], 'entertainment' => ['spent' => 330], ]; */
addAggregator
Group::addAggregator($destKey, $callbackFn): Group;
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; use \WS\Utils\Collections\Collection; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->addAggregator('names', function (Collection $collection) { $result = []; foreach ($collection as $item) { $result[] = $item['name']; } return implode(', ', $result); }); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['names' => 'potato, milk'], 'transport' => ['names' => 'taxi, airplane'], 'entertainment' => ['names' => 'Knicks game, cinema'], ]; */
所有聚合器都可以相互结合以获得所需的结果
use \WS\Utils\Collections\CollectionFactory; use \WS\Utils\Collections\Functions\Group\Group; $items = [ ['name' => 'potato', 'type' => 'groceries', 'price' => 30], ['name' => 'milk', 'type' => 'groceries', 'price' => 50], ['name' => 'taxi', 'type' => 'transport', 'price' => 100], ['name' => 'airplane', 'type' => 'transport', 'price' => 50], ['name' => 'Knicks game', 'type' => 'entertainment', 'price' => 300], ['name' => 'cinema', 'type' => 'entertainment', 'price' => 30], ]; $aggregation = Group::by('type')->avg('price', 'avg')->min('price', 'min')->max('price', 'max'); $result = CollectionFactory::from($items) ->stream() ->collect($aggregation) ; /* Result -> [ 'groceries' => ['avg' => 40, 'min' => 30, 'max' => 50], 'transport' => ['avg' => 75, 'min' => 50, 'max' => 100], 'entertainment' => ['avg' => 165, 'min' => 30, 'max' => 300], ]; */