PHPackages                             jcstrandburg/demeter - 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. jcstrandburg/demeter

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

jcstrandburg/demeter
====================

Colllection library

v0.8(7y ago)011MITPHPPHP ^7.0

Since Aug 19Pushed 7y ago1 watchersCompare

[ Source](https://github.com/jcstrandburg/Demeter)[ Packagist](https://packagist.org/packages/jcstrandburg/demeter)[ RSS](/packages/jcstrandburg-demeter/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (2)Versions (9)Used By (0)

Demeter
=======

[](#demeter)

This library provides a set of immutable collection classes that allow for an consistent, object oriented, fluent style of manipulating data collections. It is mainly inspired by LINQ from C# and the Java Stream API.

Installing
----------

[](#installing)

`composer require jcstrandburg\demeter`

Usage
-----

[](#usage)

Vanilla PHP:

```
$x = array_slice(
  array_map(
    function ($x) {return $x * 2;},
    array_filter([1, 2, 3, 4, 5], function ($x) {return $x % 2 == 1;})),
  0, 2);
```

With Demeter:

```
use function Jcstrandburg\Demeter\sequence;
use Jcstrandburg\Demeter\Lambda;

$x = sequence([1, 2, 3, 4, 5])
  ->filter(Lambda::isOdd())
  ->map(Lambda::multiplyBy(2))
  ->take(2);
```

Features
--------

[](#features)

Version History
---------------

[](#version-history)

### Unreleased

[](#unreleased)

### 0.8

[](#08)

#### Added

[](#added)

- `Extensions` static class for extension method support

### 0.7

[](#07)

#### Changes

[](#changes)

- All collection classes now implement `IteratorAggregate` instead of extending `IteratorIterator`
- `GroupedCollection::getGroupKeys` now returns a `Collection` instead of an array
- It is now possible to safely perform concurrent iterations over the same `Sequence` or derivations thereof.

For example, if `$x = sequence([1,2,3,4]);`

Before: `$x->zip($x->map(Lambda::plus(1)), Lambda::add())->toArray() == [3,6]`

Now: `$x->zip($x->map(Lambda::plus(1)), Lambda::add())->toArray() == [3,5,7,9]`

#### Removed

[](#removed)

- `LazyRewindableIterator` has been replaced with an internal implementation

#### Added

[](#added-1)

- `as_iterator` utility function

#### Deprecated

[](#deprecated)

- `as_traversable` - use `as_iterator` instead

### 0.6

[](#06)

#### Fixed

[](#fixed)

- Call the parent constructor from `ArrayGroupedCollection`

#### Changed

[](#changed)

- Breaking: Convert `GroupedCollection` to an interface, with the existing implementation becoming `ArrayGroupedCollection`
- Breaking: Convert `Grouping` to an interface, with the existing implementation becoming `ArrayGrouping`
- Make `Collection` extend `Countable`
- `xrange` now returns a `Sequence`

#### Added

[](#added-2)

- `Lambda::constant`
- `Lambda::toArray`
- `Lambda::getGroupKey`
- `Sequence::zip`
- `Sequence::chunk`
- `Sequence::join`
- `Sequence::implode`

### 0.5

[](#05)

#### Changed

[](#changed-1)

- Breaking: Changed the behavior of `HashSet` so that it acts like a proper set (hashing is used for buckets but not equality comparisons)
- Breaking: Convert `Sequence` to an interface, with the existing implementation becoming `LazySequence`
- Breaking: Convert `Collection` to an interface, with the existing implementation becoming `ArrayCollection`
- Breaking: Convert `Dictionary` to an interface, with the existing implementation becoming `ArrayDictionary`
- Breaking: Functions previously returning `HashSet` now return `Set`

#### Added

[](#added-3)

- Introduce `Set` interface which `HashSet` implements
- `Sequence::except` and `Sequence::intersect`
- `Lambda` utility class
- `dictionary` and `set` factory functions

### 0.4

[](#04)

#### Added

[](#added-4)

- `HashMap::addMany`
- `HashMap::removeMany`
- `Sequence::toDictionary`
- `Dictionary`

### 0.3

[](#03)

#### Changed

[](#changed-2)

- `sequence` and `collect` now will return their argument unmodified if is already of the correct type

#### Added

[](#added-5)

- `HashSet`
- `Sequence::asSet`
- `Sequence::first`
- `Sequence::firstOrNull`
- `Sequence::last`
- `Sequence::lastOrNull`
- `Sequence::single`
- `Sequence::singleOrNull`

### 0.2

[](#02)

#### Added

[](#added-6)

- `Sequence::groupBy`
- `GroupedCollection`
- `Grouping`

### 0.1

[](#01)

#### Added

[](#added-7)

- `Sequence`
- `Collection`
- Various utility functions
- `LazyRewindableIterator`
- `MappedIterator`
- `SkipWhileIterator`
- `TakeWhileIterator`

License
-------

[](#license)

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community7

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

Every ~11 days

Recently: every ~19 days

Total

8

Last Release

2742d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cb3a3db597b018947693eb9b8af2de14879471ecfc52b20ee5b2357edc015074?d=identicon)[jcstrandburg](/maintainers/jcstrandburg)

---

Top Contributors

[![jcstrandburg](https://avatars.githubusercontent.com/u/6415841?v=4)](https://github.com/jcstrandburg "jcstrandburg (52 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/jcstrandburg-demeter/health.svg)

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

###  Alternatives

[symfony/polyfill-uuid

Symfony polyfill for uuid functions

688335.4M63](/packages/symfony-polyfill-uuid)[spatie/error-solutions

This is my package error-solutions

6853.2M11](/packages/spatie-error-solutions)[phpflo/phpflo

Flow-based programming for PHP

2173.3k4](/packages/phpflo-phpflo)[eftec/autoloadone

AutoloadOne is a program that generates an autoload class for PHP.

403.4k](/packages/eftec-autoloadone)[ys-tools/default-theme-configuration-bundle

OroCommerce Default Theme Configuration Bundle

124.2k](/packages/ys-tools-default-theme-configuration-bundle)

PHPackages © 2026

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