benconda / collection
由生成器驱动,支持泛型,易于扩展和不可变的集合库。设计上采用延迟加载且内存友好。接受任何可迭代对象 🔥(生成器、数组、迭代器等)
Requires
- php: ^8.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.14
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^10.0
- symfony/var-dumper: ^6.2
This package is auto-updated.
Last update: 2024-09-29 08:07:39 UTC
README
由生成器驱动,支持泛型,易于扩展和不可变的集合库。设计上采用延迟加载且内存友好。接受任何可迭代对象 🔥(生成器、数组、迭代器等)
需求
使用此库需要至少php 8.2
用法
首先需要从可迭代对象创建集合,它可以是数组,或任何可迭代对象(生成器、对象迭代器等)
$collection = Collection::from($myIterable);
现在您可以应用一个或多个修改器
use BenConda\Collection\Collection; // [...] $collection = Collection::from(range(1, 10)) ->filter(callback: static fn(int $item): bool => $item > 5) ->map(on: fn(int $item): string => "The number is $item");
每次调用修改器方法时,都会返回集合的新实例,不会进行覆盖。
集合是可调用的,因此您也可以这样添加修改器
$collection = Collection::from(range(1, 10)) ( new Filter( callback: fn(int $item): bool => $item >= 5 ) ) ( new Map( callback: fn(int $item): string => "The number is $item" ) );
由于每个修改器都依赖于生成器,因此直到您开始迭代集合,什么都不会执行。
您可以这样获取第一个值
$first = $collection->first(); // $first = The number is 5
请注意,它不会遍历整个数组以返回第一个值,在幕后它只迭代1、2、3、4、5 => 数字是5
然后停止。
这是由于生成器的特性,大多数其他集合库都需要遍历整个数组以过滤它,然后再对每个过滤值进行映射,才能获取第一个值。
我们可以直接在集合 $object 上使用 foreach 迭代所有值
$collection = Collection::from(range(1, 10)) foreach ($collection as $key => $item) { // do what you want }
并且您可以像这样将整个集合转换为一个数组
$collection->toArray();
请注意,按设计我们接受任何作为键,数组将键限制为 int|string
类型,如果键类型不匹配,则将回退到递增的整数键。
修改器
可以使用修改器更改集合的迭代方式,这允许您以内存友好的方式塑造和转换数据。
一些修改器需要一些内存缓冲,并分成另一个名为 BufferedModifier
的命名空间。例如,对于 BenConda\Collection\BufferedModifier\Reverse
,为了反转,整个集合需要加载到内存中。
因此请记住,BufferedModifier
命名空间 = 将根据可迭代对象的大小消耗内存。
您可以在此文档中找到修改器列表
注意:文档正在编写中
扩展
添加自定义修改器
只需创建一个实现 BenConda\Collection\Modifier\ModifierInterface
的类
例如,对于重新索引修改器
use Generator; use BenConda\Collection\Modifier\ModifierInterface; /** * @template TKey * @template TValue * * @implements ModifierInterface<TKey, TValue> */ final class Reindex implements ModifierInterface { /** * * @param iterable<TKey, TValue> $iterable * * @return Generator<int, TValue> */ public function __invoke(iterable $iterable): Generator { foreach ($iterable as $value) { yield $value; } } }
如果您需要一些配置,只需在类中添加一个构造函数。
使用您自己的集合类
有时您需要创建自己的严格类型集合类。
为此,您可以扩展 CoreCollection 类,并仅实现所需的修改器方法。
有时您可能需要一个可变的自定义集合,对于这种情况,您可以扩展 MutableCoreCollection。您可以在此测试中找到一个示例
请注意,即使对于可变集合,您仍然依赖于生成器,因此每次您修改集合时,直到您遍历它,实际上什么都不会执行。