PHPackages                             spencerwi/lazylist - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. spencerwi/lazylist

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

spencerwi/lazylist
==================

A lazy-lists (fused-streams/generators) library for PHP &gt;=7.4

1.0.0(4y ago)03[1 PRs](https://github.com/spencerwi/PHP-LazyList/pulls)MITPHPPHP &gt;7.4.0CI failing

Since Jun 23Pushed 3mo agoCompare

[ Source](https://github.com/spencerwi/PHP-LazyList)[ Packagist](https://packagist.org/packages/spencerwi/lazylist)[ RSS](/packages/spencerwi-lazylist/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (2)Versions (3)Used By (0)

PHP-LazyList
============

[](#php-lazylist)

A lazy-list (or generator, or fused-stream, or seq, or whatever) library for PHP.

Supports PHP &gt;=7.4.

Usage
-----

[](#usage)

### Creation

[](#creation)

Lazy lists can be created from arrays

```
$lazyList = \Spencerwi\Lazy_list\LazyList::fromArray([1,2,3,4,5]);
```

They can also be created from callables that take an `int` index and return either some value or else `\Spencerwi\Lazy_list\LazyList::STOP_ITERATION` to signal the end of the list.

```
$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`

[](#map)

You can map over a lazy list, and it's a "lazy" map, so it doesn't call your mapper function until you actually force evaluation of the list.

```
$mapperWasCalled = false;
$squares = $lazyList->map(function($i): int use (&$mapperWasCalled) {
    $mapperWasCalled = true;
    return $i * $i;
});
// $mapperWasCalled is still false!
```

### `filter`

[](#filter)

You can apply a filter predicate to a lazy list, and it'll "lazily" apply the filter, meaning that your filter function doesn't get called until you actually force evaluation of the list.

```
$filterFnWasCalled = false;
$oddNumbers = $lazyList->filter(function (int $i): bool use (&$filterFnWasCalled) {
    $filterFnWasCalled = true;
    return ($i % 2 === 1);
});
// $filterFnWasCalled is still false!
```

### Iteration

[](#iteration)

You can also iterate over a lazy list more traditionally; it's an iterator.

```
foreach ($squares as $square) {
    echo $square . "\n";
}
/* Output:
 * 1
 * 4
 * 9
 * 16
 * 25
 */
```

It even supports index =&gt; value iteration:

```
foreach ($squares as $index => $square) {
    echo $index . ": " . $square . "\n";
}
/* Output:
 * 0: 1
 * 1: 4
 * 2: 9
 * 3: 16
 * 4: 25
 */
```

### `take($count)`

[](#takecount)

You can also take just a certain number of elements from the beginning:

```
$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)

You can more directly dump the whole list out to an array with `toArray()`:

```
$l = \Spencerwi\Lazy_list\LazyList::fromArray([1,2,3,4,5]);
$->toArray(); // [1,2,3,4,5]
```

**BE VERY CAREFUL WITH THIS**, as you can wind up using a generator to create an infinite list (if your generator never returns null), which *will* cause an infinite loop if you call toArray() on it. Unfortunately, there's no way to know ahead of time that a generator is infinite, or else we'd have the list throw an exception on trying to toArray() an infinite LazyList.

### `reduce()`

[](#reduce)

Alongside `map`, you also have its friend `reduce`, which takes an initial value, and a function that works "pairwise" along the list calling a function you provide, first on initial and the first element, then on the previous result and the second element, then on *that* result and the third element, and so on.

```
$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.
```

If you try to "reduce" an empty list, you just get the "initial" value back. That's why it's there.

```
$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
```

**THIS OPERATION IS "EAGER"**, meaning that **it evaluates the whole list**. As with `toArray()`, that means that **if you have an infinite LazyList, `reduce()` will cause an infinite loop.**

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance54

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1783d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2829379?v=4)[Spencer Williams](/maintainers/spencerwi)[@spencerwi](https://github.com/spencerwi)

---

Top Contributors

[![spencerwi](https://avatars.githubusercontent.com/u/2829379?v=4)](https://github.com/spencerwi "spencerwi (13 commits)")

---

Tags

streamgeneratorlistlazy

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/spencerwi-lazylist/health.svg)

```
[![Health](https://phpackages.com/badges/spencerwi-lazylist/health.svg)](https://phpackages.com/packages/spencerwi-lazylist)
```

###  Alternatives

[symfony/maker-bundle

Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.

3.4k111.1M568](/packages/symfony-maker-bundle)[simplesoftwareio/simple-qrcode

Simple QrCode is a QR code generator made for Laravel.

2.9k27.6M92](/packages/simplesoftwareio-simple-qrcode)[react/stream

Event-driven readable and writable streams for non-blocking I/O in ReactPHP

688126.8M194](/packages/react-stream)[ihor/nspl

Non-standard PHP library (NSPL) - functional primitives toolbox and more

381368.5k](/packages/ihor-nspl)[okipa/laravel-table

Generate tables from Eloquent models.

56752.8k](/packages/okipa-laravel-table)[alexandre-daubois/lazy-stream

Write data to streams, only when it is really needed to.

755.7k](/packages/alexandre-daubois-lazy-stream)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
