spencerwi / lazylist
PHP >=7.4 的懒列表(fused-streams/generators)库
Requires
- php: >7.4.0
Requires (Dev)
- phpunit/phpunit: ^9
- vimeo/psalm: ^4.8
This package is auto-updated.
Last update: 2024-09-23 07:33:06 UTC
README
PHP 的懒列表(或生成器,或融合流,或 seq,或其他)库。
支持 PHP >=7.4。
用法
创建
懒列表可以从数组创建
$lazyList = \Spencerwi\Lazy_list\LazyList::fromArray([1,2,3,4,5]);
它们也可以从接受一个 int
索引并返回某个值或返回 \Spencerwi\Lazy_list\LazyList::STOP_ITERATION
来表示列表结束的函数创建。
$lazyList2 = new \Spencerwi\Lazy_list\LazyList(function(int $i) { if ($i < 10) { return $i; } else { return \Spencerwi\Lazy_list\LazyList::STOP_ITERATION; } }); // This amounts to a LazyList containing [0,1,2,3,4,5,6,7,8,9].
map
你可以映射一个懒列表,并且它是一个“懒”映射,所以它不会在真正强制评估列表之前调用你的映射函数。
$mapperWasCalled = false; $squares = $lazyList->map(function($i): int use (&$mapperWasCalled) { $mapperWasCalled = true; return $i * $i; }); // $mapperWasCalled is still false!
filter
你可以将过滤器谓词应用于懒列表,它将“懒”地应用过滤器,这意味着你的过滤器函数不会在真正强制评估列表之前被调用。
$filterFnWasCalled = false; $oddNumbers = $lazyList->filter(function (int $i): bool use (&$filterFnWasCalled) { $filterFnWasCalled = true; return ($i % 2 === 1); }); // $filterFnWasCalled is still false!
迭代
你也可以更传统地迭代懒列表;它是一个迭代器。
foreach ($squares as $square) { echo $square . "\n"; } /* Output: * 1 * 4 * 9 * 16 * 25 */
它甚至支持索引 => 值迭代
foreach ($squares as $index => $square) { echo $index . ": " . $square . "\n"; } /* Output: * 0: 1 * 1: 4 * 2: 9 * 3: 16 * 4: 25 */
take($count)
你也可以从开始取一定数量的元素
$l = \Spencerwi\Lazy_list\LazyList::fromArray([1,2,3,4,5]); $l->take(2); // returns the array [1,2] // What happens when we take too many? $l->take(99); // we get the whole list as an array: [1,2,3,4,5]
toArray()
你可以使用 toArray()
将整个列表直接转换为数组
$l = \Spencerwi\Lazy_list\LazyList::fromArray([1,2,3,4,5]); $->toArray(); // [1,2,3,4,5]
请务必小心使用此方法,因为如果你使用生成器创建一个无限列表(如果生成器永远不会返回 null),则调用 toArray() 将会导致无限循环。不幸的是,没有方法可以预先知道生成器是无限的,否则我们会在尝试将无限 LazyList 转换为 toArray() 时抛出异常。
reduce()
除了 map
之外,你还有它的朋友 reduce
,它接受一个初始值和一个在列表上“成对”工作的函数,它调用你提供的函数,首先在初始值和第一个元素上,然后在上一个结果和第二个元素上,然后在 那个 结果和第三个元素上,依此类推。
$l = \Spencerwi\Lazy_list\LazyList::fromArray([2,3,4]); $sum = $l->reduce(1, function(int $previous, int $current) { return $previous + $current; }); // $sum is now ((1+2)+3)+4, that is, 10.
如果你尝试“归约”一个空列表,你只会得到“初始”值。这就是为什么需要它。
$l = \Spencerwi\Lazy_list\LazyList::fromArray([]); $sum = $l->reduce(1, function(int $previous, int $current) { return $previous + $current; }); // $sum is now just 1, since the list was empty
此操作是“急切”的,意味着它评估整个列表。与 toArray()
一样,这意味着如果你有一个无限 LazyList,则 reduce()
将导致无限循环。