大脚侠 / php-iter
Requires
- php: >=8.1
Requires (Dev)
- phpunit/phpunit: ^9
This package is not auto-updated.
Last update: 2024-09-21 17:14:44 UTC
README
为PHP提供类似Rust的迭代器。
警告:此包仅是一个概念验证,不应在生产环境中使用。
特性
- 惰性迭代器;
- 可链方法;
- 精心设计、连贯的API。
优点
- 极大地提高了代码的可读性。
缺点
- 与经典
for
循环相比,运行时成本较高(大约慢15倍!)。但对于小循环(小于1000个元素),这种运行时成本可能是可以接受的。
安装
在您的PHP项目中,运行
composer require dajoha/php-iter
基本用法
$numbers = [1, 30, 50, 123, 3, 5, 100, 3780];
$output = iter($numbers) // Convert the input array to an `IteratorInterface`
->filter(fn($n) => $n > 100) // Keep only numbers which are > 100
->map(fn($n) => "Number $n") // Map each remaining number to a formatted string
->join("\n"); // Reduce the iterator to a single string
echo "$output\n";
输出
Number 123
Number 3780
更多示例
请参阅此存储库中的/examples
目录以获取更多用法示例。
API概述
API提供了一个中心接口:IteratorInterface
,它扩展了原生的PHP Iterator
,但给它提供了更多的能力。
有两种原生的类实现了IteratorInterface
- 生成器,可以从任何输入源(如简单数组或任何实现了原生PHP
Iterator
的任何东西)创建IteratorInterface
; - 修饰器,将给定的
IteratorInterface
转换成另一个。
一旦创建了迭代器,就必须以某种方式“消费”它,以获得有用的结果(最基本的方式是调用原生PHP方法Iterator::next()
)。在此文档中,这被称为迭代器的归约。在IteratorInterface
中提供了某些方法,以便处理非常常见的归约操作,如转换为数组(toValues()
)、对数字求和(sum()
)... 所有这些归约方法都在AbstractIterator
中实现,该包中的每个类都基于它。
生成器
生成器是可以从任何类型的输入参数构建的IteratorInterface
。
例如,一个生成器可以是提供以下内容的类
- 一个简单的具体值列表,如
[78, 'foo', 'bar']
; - 通过提供特定时间段作为输入,获取著名音乐家的列表;
- 素数无限列表。
修饰器
修饰器是一个IteratorInterface
,它接受一个可迭代对象作为第一个输入,并在消费时转换内部可迭代对象的结果。
每个原生修饰器类在IteratorInterface
中都有一个专用方法,允许将其与其他修饰器(或与最终的归约方法)链在一起。
例如
- “映射”修饰器迭代器转换其内部迭代器的每个值。
- “过滤”修饰器迭代器仅提供满足给定条件的值。
归约器
归约器是方法(通常在AbstractIterator
内部实现),通过消费其迭代器的元素(不一定所有元素,尽管通常是这种情况)将给定的迭代器转换为一个最终值。
例如,AbstractIterator::sum()
是一个归约方法,它消费迭代器的所有元素(假设它们是数字),并返回这些元素的总和。
原生生成器的摘要
“Iter”生成器
“Iter”类是最基本的生成器:它简单地包装了给定的可迭代对象,它可以是一个
- PHP数组(通过内部使用
ArrayIterator
); - PHP
Iterator
。 - 一个php
IteratorAggregate
(通过尝试获取内部迭代器); - 一个php可调用对象(通过将其包装到
Func
生成器中)。
iter()
全局函数
Iter
生成器使用非常普遍,因此提供了一个全局函数来包装其构造函数:iter()
。
其他原生生成器
类 | 描述 |
---|---|
AsciiChars | 遍历字符串中的字节 |
Chain | 将多个子迭代器链接在一起 |
Chars | 遍历字符串中的utf-8字符 |
Counter | 生成自定义的数字序列 |
Forever | 无限重复一个值 |
Func | 永远返回函数调用更新的结果 |
Letters | 遍历已知的字符序列 |
Zip | 同时遍历多个迭代器 |
Alternate | 交替多个迭代器的值 |
Interleave | 交错两个迭代器的值 |
IteratorInterface
方法总结
修改器方法
修改器方法是将实际迭代器转换为另一个迭代器的。以下是原生修改器方法列表
chunks() // Create an iterator over chunks of N elements
filter() // Filter the values of the iterator by using a callable
filterKeys() // Filter the keys of the iterator by using a callable
map() // Map the values of the iterator by using a callable
mapKeys() // Map the keys of the iterator by using a callable
mapKeyValues() // Map the keys and values of the iterator by using a callable
skip() // Skip the given number of elements at the start of the iterator
flatten() // Flatten the iterator, by assuming that each element is iterable itself
limit() // Limit the number of elements of the iterator
slice() // A combination of skip() and limit()
zip() // Iterate over multiple iterators simultaneously
alternate() // Alternate values of multiple iterators
interleave() // Interleaves the values of the iterator with another iterator
loop() // Loop over the iterator a certain number of times
run() // Just run the given callable on each item
apply() // Wrap the iterator into a custom iterator
消耗/减少方法
一旦最终创建了所需的迭代器,则可以调用一个(且仅一个)“减少”方法。以下是减少方法列表
isFound() // Advance the iterator until the given predicate returns `true`
find() // Advance the iterator until the given predicate returns `true`
first() // Return the first value of the iterator
last() // Return the last value of the iterator. Consume the iterator entirely.
nth() // Return the given Nth value of the iterator. Consume the iterator until this item is reached
reduce() // Reduce the iterator to a single value
all() // Check if all the iterator values fill the requirement of the given predicate
any() // heck if at least one of the iterator values fills the requirement of the given predicate
count() // Return the number of items of the iterator. Consume the iterator entirely
min() // Return the minimum value of the iterator
max() // Return the minimum value of the iterator
sum() // Return the sum of the values of the iterator
average() // Return the average of the values of the iterator
join() // Join all the values of the iterator into a single string
toValues() // Return an array of all the values of the iterator
toArray() // Return an array of all the values of the iterator
consume() // Consume all the iterator (like toValues(), but don't return anything)
运行测试套件
$ composer create-project dajoha/php-iter
$ cd php-iter
$ vendor/bin/phpunit