apk / iterators
*已弃用:请参阅 apk/fitter* 一系列可链式迭代器和迭代器处理方法。
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: 4.8.*
This package is auto-updated.
Last update: 2024-09-27 06:39:34 UTC
README
此项目不再维护。请使用 apk/fitter
新版本包含相同的迭代器,并增加了更多类型和功能。
Fitter 需要 PHP 7.x,因此如果您尚未升级,您可以暂时继续使用此软件包。
迭代器
一系列可链式迭代器和处理方法。
安装
Composer
将以下内容添加到您的 composer.json 文件中
{
"require": {
"apk/iterators": "^1.0"
}
}
示例
处理 CSV 文件
读取 CSV 文件,为列分配有意义的名称,过滤无效的电子邮件地址,使用标准的 PHP SplFileObject 来展示与其他迭代器的集成
$csvIterator = new \SplFileObject('emails.csv', 'r');
$csvIterator->setFlags(\SplFileObject::READ_CSV);
$csvIterator->setCsvControl(',', '"');
$processIterator = new Iterator($csvIterator);
$result = $processIterator
->walk(function($el) {
return [
'email' => $el[0],
'name' => $el[1],
'surname' => $el[2],
'status' => $el[3]
];
})->filter(function($el) {
return (bool)filter_var($el['email'], FILTER_VALIDATE_EMAIL);
})->toArray()
;
这将使用文件中的第一行作为列名(第二个参数中的 "true"),逗号作为分隔符(第三个参数),双引号作为封装符(第四个参数)。
处理 PDO 结果集
获取用户列表,统计他们各自的状态数量。
这只是一个示例,更好的方法是使用 SQL 中的 GROUP BY。
$pdo = new \PDO('sqlite:///tmp/db.sqlite');
$stmt = $pdo->query('select * from users');
$processIterator = new Iterator($stmt);
$result = $processIterator
->map(function($el) {
return [ $el['status'], $el ];
})->reduce(function($el, $prev) {
if (is_null($prev)) { $prev = 0; }
return $prev + 1;
})->toArray();
您可以在过滤后使用 ArrayIterator 将 PDO 结果集流式传输
$pdo = new \PDO('sqlite:///tmp/db.sqlite');
$stmt = $pdo->query('select * from users');
$stmt->setFetchMode(\PDO::FETCH_ASSOC);
Iterator::create($stmt)
->filter(function($el) {
return $el['status'] == ENABLED;
})
->collect()
;
当然,所有处理器都可以在 create() 和 to() 之间使用。在这种情况下,只有启用的用户将被写入。
使用手动组合
如果您不喜欢 "流畅" 接口并更喜欢手动组合,您当然可以这样做。这个(第一个示例)
$csvIterator = new \SplFileObject('emails.csv', 'r');
$csvIterator->setFlags(\SplFileObject::READ_CSV);
$csvIterator->setCsvControl(',', '"');
$processIterator = new Iterator($csvIterator);
$result = $processIterator
->walk(function($el) {
return [
'email' => $el[0],
'name' => $el[1],
'surname' => $el[2],
'status' => $el[3]
];
})->filter(function($el) {
return (bool)filter_var($el['email'], FILTER_VALIDATE_EMAIL);
})->toArray()
可以重写为这样
$csvIterator = new \SplFileObject('emails.csv', 'r');
$csvIterator->setFlags(\SplFileObject::READ_CSV);
$csvIterator->setCsvControl(',', '"');
$result = new Filter(
new Walk(
new Iterator($csvIterator),
function($el) {
return [
'email' => $el[0],
'name' => $el[1],
'surname' => $el[2],
'status' => $el[3]
];
}
),
function($el) {
return (bool)filter_var($el['email'], FILTER_VALIDATE_EMAIL);
}
)->toArray();
一般描述
迭代器方法可以分为 "适配器" 和 "消费者"。迭代器可以通过生成器创建,并通过消费者产生输出。
适配器包括:
filter 返回一个 Filter Iterator,它进一步只返回满足由给定回调定义的条件的原始迭代器的值。
walk 返回一个 Walk Iterator,它进一步遍历原始值,并将给定的回调应用于每个值。
map 返回一个 Map Iterator,它将原始迭代器中的每个值映射到元组 [key, value],适合由 reduce 处理。
skip 返回一个 Skip Iterator,它在处理时跳过原始迭代器的 n 个值。
take 返回一个 Take Iterator,它在处理时只取原始迭代器的 n 个值。
zip 返回一个 Zip Iterator,它允许迭代多个迭代器,并返回每个迭代器元素的数组。
消费者包括:
min 接受一个排序比较函数并返回迭代器中的最小值
max 接受一个排序比较函数并返回迭代器中的最大值
avg 接受一个将迭代器值转换为数字的函数并返回平均值
find 接受一个用于过滤迭代器值的函数并返回第一个匹配的值
fold 递归地将给定的函数应用于迭代器的每个值以及前一个结果,并返回一个单一值
减少 递归地将函数应用于索引迭代器,按索引分组减少
运行 一种特殊的消费者,将遍历迭代器中的所有元素。与消费者对象和walk()配合使用很有用
toArray 通过依次遍历所有处理器,从迭代器生成PHP数组。警告:map()生成重叠键。将map()的结果转换为数组将只保留每个键的最新值
collect 通过依次遍历所有处理器,从迭代器生成ArrayIterator或填充提供的ArrayAccess-able对象。 警告:map()生成重叠键。将map()的结果转换为ArrayIterator或ArrayObject将只保留每个键的最新值
toCollector 将迭代器流式传输到收集器
生成器是
Range 生成数字范围。
StringWords 逐词读取和处理字符串。
消费者包括:
- ArrayIterator 不仅是一个收集器,也是PHP的\ArrayIterator的包装器,提供本库的所有功能。
适配器
适配器包装(或装饰)迭代器,以返回一个新迭代器,允许在处理过程中过滤/更改数据。
filter
待办事项:过滤描述
walk
待办事项:Walk描述
map
待办事项:map描述
skip
待办事项:skip描述
take
待办事项:take描述
zip
待办事项:zip描述
消费者
消费者,如名称所示,“消费”迭代器并返回一个聚合值。
min
待办事项:Min描述
max
待办事项:Max描述
avg
待办事项:Avg描述
find
待办事项:Find描述
fold
待办事项:Fold描述
reduce
待办事项:Reduce描述
run
待办事项:run描述
toArray
待办事项:toArray描述
collect
待办事项:collect描述
toCollector
待办事项:toCollector描述
生成器
生成器,如名称所示,生成一个迭代器,该迭代器将遍历一组数据。
Range
待办事项:Range描述
StringWords
待办事项:StringWords描述
消费者
消费者是特殊的迭代器消费者,可以将迭代器处理结果写入某种类型的输出(文件、流、数据库等)
ArrayIterator
待办事项:ArrayObject描述
如何帮助
这仍然是一个正在进行中的项目。如果您想帮忙,可以通过以下几种方式
编写文档。我太懒了,不想写。 :D 这不应该很难,只需查看单元测试并将其翻译成英文即可。
编写更多测试。可能有一百万种边缘情况我没有考虑。
建议有用的处理器、消费者和编写器。我无法保证它们将被实现,但我会考虑它们。
帮助调试:测试它,使用它,看看它在哪里失败,可能修复它并提交Pull Request。
编写更多组件并提交Pull Request,但在之前请与我联系。 ;) 可能最好使用这些组件编写一个库。
代码风格主要是PSR-1和PSR-2,有一些例外(“必须”,“应该”按照PSR定义)
- 必须使用制表符而不是空格
- 必须使用大括号进行循环和条件语句(即使是一行代码)
- “static”应该在可见性声明(public、protected、private)之前。
- 可能是我现在想不起来的其他东西。 :D
如果你需要,我可以提供PHPStorm的自动格式化配置。
待办事项
- [ ] toJson,可能是“流式”
- [ ] 改进文档
版权
(c)版权所有 Alessandro Pellizzari alex@amiran.it
在BSD许可下分发。
有关完整的版权和许可信息,请参阅与此源代码一起分发的LICENSE文件。