PHPackages                             xp-forge/sequence - 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. xp-forge/sequence

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

xp-forge/sequence
=================

Data sequences

v10.4.0(7mo ago)113.8k↓67%1[2 PRs](https://github.com/xp-forge/sequence/pulls)2BSD-3-ClausePHPPHP &gt;=7.0.0CI passing

Since Sep 27Pushed 7mo ago4 watchersCompare

[ Source](https://github.com/xp-forge/sequence)[ Packagist](https://packagist.org/packages/xp-forge/sequence)[ Docs](http://xp-framework.net/)[ RSS](/packages/xp-forge-sequence/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (53)Used By (2)

Data sequences
==============

[](#data-sequences)

[![Build status on GitHub](https://github.com/xp-forge/sequence/workflows/Tests/badge.svg)](https://github.com/xp-forge/sequence/actions)[![XP Framework Module](https://raw.githubusercontent.com/xp-framework/web/master/static/xp-framework-badge.png)](https://github.com/xp-framework/core)[![BSD Licence](https://raw.githubusercontent.com/xp-framework/web/master/static/licence-bsd.png)](https://github.com/xp-framework/core/blob/master/LICENCE.md)[![Requires PHP 7.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-7_0plus.svg)](http://php.net/)[![Supports PHP 8.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-8_0plus.svg)](http://php.net/)[![Latest Stable Version](https://camo.githubusercontent.com/c4e4418f70fb470bbd006c719a60d68fd0819767ed6321427ea27f029210ea2e/68747470733a2f2f706f7365722e707567782e6f72672f78702d666f7267652f73657175656e63652f76657273696f6e2e737667)](https://packagist.org/packages/xp-forge/sequence)

This API allows working with data sequences of different kinds in a functional style, e.g. map/reduce.

Examples
--------

[](#examples)

### Sequence

[](#sequence)

Instances of the `util.data.Sequence` class can be created from iterable input, either an in-memory structure or a stream of data, e.g. read from a network socket. The Sequence class provides intermediate (work on single elements, return a new Sequence) and terminal (consume all elements, returning a single value) operations.

```
use util\data\{Sequence, Collectors, Aggregations};

$return= Sequence::of([1, 2, 3, 4])
  ->filter(fn($e) => 0 === $e % 2)
  ->toArray()
;
// $return= [2, 4]

$return= Sequence::of([1, 2, 3, 4])
  ->map(fn($e) => $e * 2)
  ->toArray()
;
// $return= [2, 4, 6, 8]

$i= 0;
$return= Sequence::of([1, 2, 3, 4])
  ->counting($i)
  ->reduce(0, fn($a, $b) => $a + $b)
;
// $i= 4, $return= 10

$names= Sequence::of($this->people)
  ->map('com.example.Person::name')
  ->collect(Collectors::joining(', '))
;
// $names= "Timm, Alex, Dude"

$experience= Sequence::of($this->employees)
  ->collect(Collectors::groupingBy(
    fn($e) => $e->department(),
    Aggregations::average(fn($e) => $e->years())
  ))
;
// $experience= util.collections.HashTable[2] {
//   Department("A") => 12.8
//   Department("B") => 3.5
// }
```

### Optional

[](#optional)

Instances of the `util.data.Optional` class are thin wrappers around possible NULL values. The operations provided by Optional class help in reducing conditional code:

```
use util\data\Optional;

$first= Optional::of($repository->find($user));
if ($first->present()) {
  $user= $first->get();    // When Repository::find() returned non-null
}

$user= $first->orElse($this->currentUser);
$user= $first->orUse(fn() => $this->currentUser());

$name= $first
  ->filter(fn($user) => $user->isActive())
  ->whenAbsent($this->currentUser)
  ->whenAbsent(fn() => $this->guestUser())
  ->map('com.example.User::name')
  ->get()
;
```

Creation operations
-------------------

[](#creation-operations)

Sequences can be created from a variety of sources, and by using these static methods:

- **of** - accepts PHP arrays (zero-based as well as associative), all traversable data structures including `lang.types.ArrayList` and `lang.types.ArrayMap` as well as anything from `util.collections`, `util.XPIterator` instances, PHP iterators and iterator aggregates, PHP 5.5 generators (*yield*), as well as sequences themselves. Passing NULL will yield an empty sequence.
- **iterate** - Iterates starting with a given seed, applying a unary operator on this value and passing the result to the next invocation, forever. Combine with `limit()`!
- **generate** - Iterates forever, returning whatever the given supplier function returns. Combine with `limit()`!

Intermediate operations
-----------------------

[](#intermediate-operations)

The following operations return a new `Sequence` instance on which more intermediate or terminal operations can be invoked:

- **skip** - Skips past elements in the beginning. Using `skip(4)` skips the first four elements, `skip(function($e) { return 'initial' === $e; })` will skip all elements which equal to the string *initial*.
- **limit** - Stops iteration when limit is reached. Using `limit(10)` stops iteration once ten elements have been returned, `limit(function($e) { return 'stop' === $e; })` will stop once the first element equal to the string *stop* is encountered.
- **filter** - Filters the sequence by a given criterion. The new sequence will only contain values for which it returns true. Accepts a function or a `util.Filter` instance.
- **map** - Maps each element in the sequence by applying a function on it and returning a new sequence with the return value of that function.
- **except** - Returns the sequence with all values except the ones given.
- **peek** - Calls a function for each element in the sequence; especially useful for debugging, e.g. `peek('var_dump', [])`.
- **counting** - Increments the integer given as its argument for each element in the sequence.
- **collecting** - Collects elements in this sequence to a `util.data.ICollector` instance. Unlike the terminal operation below, passes the elements on.
- **flatten** - Flattens sequences inside the sequence and returns a new list containing all values from all sequences.
- **distinct** - Returns a new sequence which only consists of unique elements. Uniqueness is calculated using the `util.Objects::hashOf()` method by default (*but can be passed another function*).
- **zip** - Combines values from this sequence with a given enumerable value, optionally using a given transformation function.
- **concat** - Concatenates this sequence with a given enumerable.
- **sorted** - Returns a sorted collection. Can be invoked with a comparator function, a `util.Comparator` instance or the sort flags from PHP's sort() function (e.g. `SORT_NUMERIC | SORT_DESC`).
- **chunked** - Returns a chunked stream with chunks not exceeding the given size. The last chunk may have a smaller size.
- **windowed** - Returns a sliding window stream - a list of element ranges that you would see if you were looking at the collection through a sliding window of the given size.

Terminal operations
-------------------

[](#terminal-operations)

The following operations return a single value by consuming all of the sequence:

- **toArray** - will return a PHP array with zero-based keys
- **toMap** - will return a PHP associative array
- **first** - will return the first element as an `util.data.Optional` instance. A value will be present if the sequence was not empty.
- **single** - like `first()`, but raises an exception if more than one element is contained in the sequence.
- **count** - will return the number of elements in the sequence
- **min** - returns the smalles element. Compares numbers by default but may be given a comparator function or a `util.Comparator` instance.
- **max** - same as `min()`, but returns the largest element instead.
- **each** - Applies a given function to each element in the sequence, and returns the number of elements. Can be invoked without a function to consume "silently".
- **reduce** - Perform a reduction on the elements in this sequence.
- **collect** - Pass all elements in this sequence to a `util.data.ICollector` instance.

Iteration
---------

[](#iteration)

To use controlled iteration on a sequence, you can use the `foreach` statement or receive a "hasNext/next"-iterator via the `iterator()` accessor. If the sequence is based on seekable data (rule of thumb: all in-memory structures will be seekable), these operations can be repeated with the same effect. Otherwise, a `util.data.CannotReset` exception will be raised (e.g., for data streamed from a socket).

Further reading
---------------

[](#further-reading)

- The [java.util.stream package](http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
- [JDK8: Stream style](http://de.slideshare.net/SergeyKuksenko/jdk8-stream-style) - by Sergey Kuksenko, Performance Engineering at Oracle on Dec 03, 2013
- [Processing Data with Java SE 8 Streams, Part 1](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html)
- [Lazy sequences implementation for Java 8](https://github.com/nurkiewicz/LazySeq)

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance62

Regular maintenance activity

Popularity26

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity71

Established project with proven stability

 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

Every ~91 days

Recently: every ~359 days

Total

45

Last Release

233d ago

Major Versions

v5.2.0 → v6.0.02016-07-23

v6.6.0 → v7.0.02017-05-14

v7.0.1 → v8.0.02017-05-29

v8.0.4 → v9.0.02020-04-10

v9.3.0 → v10.0.02021-10-21

PHP version history (4 changes)v0.7.4PHP &gt;=5.4.0

v4.1.0PHP &gt;=5.5.0

v6.0.0PHP &gt;=5.6.0

v9.0.0PHP &gt;=7.0.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/07d18d882c8b4aaf3466432f64018214f2771eda333202175431ee7233795376?d=identicon)[thekid](/maintainers/thekid)

---

Top Contributors

[![thekid](https://avatars.githubusercontent.com/u/696742?v=4)](https://github.com/thekid "thekid (476 commits)")

---

Tags

collectfiltermapphpreducestreamxp-frameworkmodulexp

### Embed Badge

![Health badge](/badges/xp-forge-sequence/health.svg)

```
[![Health](https://phpackages.com/badges/xp-forge-sequence/health.svg)](https://phpackages.com/packages/xp-forge-sequence)
```

PHPackages © 2026

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