apk / fitter
Requires
- php: >=7
Requires (Dev)
- phpunit/phpunit: ^6
This package is auto-updated.
Last update: 2024-09-19 10:24:48 UTC
README
一个类和特质的集合,受Rust启发,易于以函数方式开发。
安装
Composer
将以下内容添加到您的 composer.json 中
{
"require": {
"apk/fitter": "^0.10"
}
}
示例
处理CSV文件
读取CSV文件,为列分配有意义的名称,过滤掉无效的电子邮件地址,使用标准的PHP SplFileObject显示与其他迭代器的集成。
$csvIterator = new \SplFileObject('emails.csv', 'r');
$csvIterator->setFlags(\SplFileObject::READ_CSV);
$csvIterator->setCsvControl(',', '"');
$processIterator = new Iterator($csvIterator);
$result = $processIterator
->map(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
->mapKey(function($el) {
return [ $el['status'], $el ];
})->reduce(function($el, $prev) {
if (is_null($prev)) { $prev = 0; }
return $prev + 1;
})->toArray();
您可以在过滤后通过流将PDO结果集放入ArrayIterator中
$pdo = new \PDO('sqlite:///tmp/db.sqlite');
$stmt = $pdo->query('select * from users');
$stmt->setFetchMode(\PDO::FETCH_ASSOC);
Iterator::from($stmt)
->filter(function($el) {
return $el['status'] == ENABLED;
})
->collect()
;
自然地,所有处理器都可以在from()和collect()之间使用。在这种情况下,只有启用的用户将被写入。
使用手动组合
如果您不喜欢 "流畅" 的界面并更喜欢手动组合,您当然可以这样做。这个(第一个示例)
$csvIterator = new \SplFileObject('emails.csv', 'r');
$csvIterator->setFlags(\SplFileObject::READ_CSV);
$csvIterator->setCsvControl(',', '"');
$processIterator = new Iterator($csvIterator);
$result = $processIterator
->map(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 Map(
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();
一般描述
迭代器方法可以分为 "适配器" 和 "消费者"。迭代器可以通过生成器创建,并通过消费者产生输出。
适配器包括
chain 返回一个ChainIterator,它将逐个返回传递给第一个迭代器的所有元素,然后是第二个,依此类推。
filter 返回一个Filter Iterator,它将返回满足给定回调定义的条件的原始迭代器的值。
filterMap 返回一个FilterMap Iterator,它将遍历原始值,并使用给定的回调函数对每个值进行操作。如果函数返回Option::Some值,则计算值将通过。如果返回None,则该值将不在结果中。
map 返回一个Map Iterator,它将遍历原始值,并对每个值应用给定的回调函数。
mapKey 返回一个MapKey Iterator,它将原始迭代器中的每个值映射到元组[key, value],适合由reduce处理。
skip 返回一个Skip Iterator,它在处理原始迭代器时会跳过n个值。
take 返回一个Take Iterator,它在处理原始迭代器时只取n个值。
zip 返回一个Zip Iterator,它允许迭代多个迭代器,返回每个迭代器的元素数组。
消费者包括
min 采取排序比较函数并返回迭代器中的最小值
max 采取排序比较函数并返回迭代器中的最大值
avg 采取将迭代器值转换为数字的函数并返回平均值
find 接收一个函数来过滤迭代器中的值,并返回第一个匹配的值
fold 将给定的函数递归地应用于迭代器的每个值以及前一个结果,并返回一个单一值
reduce 将函数递归地应用于索引迭代器以按索引进行分组
run 一种特殊的消费者,它将遍历迭代器中的所有元素。与消费者对象和walk()结合使用很有用
toArray 通过依次遍历所有处理器,从迭代器生成PHP数组。**警告**:mapKey()生成重叠的键。将mapKey()的结果转换为数组将只保留每个键的最新值
collect 通过依次遍历所有处理器,从迭代器生成ArrayIterator或填充提供的可访问的ArrayAccess对象)。**警告**:mapKey()生成重叠的键。将mapKey()的结果转换为ArrayIterator或ArrayObject将只保留每个键的最新值
toCollector 将迭代器流式传输到收集器
生成器是
Range 生成一系列数字
StringWords 按单词读取并处理字符串
消费者包括
- ArrayIterator 不仅是一个收集器,还是PHP的\ArrayIterator的包装器,提供所有这个库的函数
适配器
适配器包装(或装饰)迭代器,以返回一个新迭代器,允许在处理过程中过滤/更改数据
chain
TODO:链描述
filter
TODO:过滤器描述
filterMap
TODO:FilterMap描述
map
TODO:Walk描述
mapKey
TODO:map描述
skip
TODO:skip描述
take
TODO:take描述
zip
TODO:zip描述
消费者
消费者,顾名思义,“消费”迭代器并返回一个聚合值。
min
TODO:Min描述
max
TODO:Max描述
avg
TODO:Avg描述
find
TODO:Find描述
fold
TODO:Fold描述
reduce
TODO:Reduce描述
run
TODO:run描述
toArray
TODO:toArray描述
collect
TODO:collect描述
toCollector
TODO:toCollector描述
生成器
生成器,顾名思义,生成一个迭代器,该迭代器将遍历一组数据。
Range
TODO:Range描述
StringWords
TODO:StringWords描述
消费者
消费者是特殊的迭代器消费者,可以将迭代器处理结果写入某种类型的输出(文件、流、数据库等)
ArrayIterator
TODO:ArrayObject描述
如何帮助
这(仍然)是一个正在进行中的工作。如果您想帮忙,可以通过几种方式来做
编写文档。我太懒了,不想做。:D 这不应该很难,只需查看单元测试并将它们翻译成英文即可。
编写更多测试。可能有一百万种边缘情况我没有考虑到。
建议有用的处理器、消费者和编写器。我无法保证它们会被实现,但我会考虑它们。
帮助调试:测试它,使用它,看看它在哪里出错,可能修复它并发送Pull Request。
编写更多组件并发送拉取请求,但在发送前请先联系。;) 使用这些组件编写库可能更好。
代码风格主要是PSR-1和PSR-2,但有例外(根据PSR定义的“必须”和“应该”)
- 必须使用制表符而不是空格
- 必须使用花括号表示循环和条件语句(即使是一行代码)
- "static" 应该在可见性声明(public、protected、private)之前
- 可能还有一些我现在没想起来的其他事项。 :D
如果需要,我可以提供PHPStorm的自动格式化配置。
待办事项
- [ ] toJson,可能是“流式”
- [ ] 改进文档
版权
(c) 版权所有 2015-2017 Alessandro Pellizzari alex@amiran.it
在BSD许可下分发。
有关完整的版权和许可信息,请参阅与此源代码一起分发的LICENSE文件。