apk/fitter

受Rust启发的函数类型和迭代器。

0.10.2 2017-07-04 22:00 UTC

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 将迭代器流式传输到收集器

生成器是

消费者包括

  • 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文件。