PHPackages                             mf/collections-php - 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. mf/collections-php

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

mf/collections-php
==================

Collections for PHP - It's basically a syntax sugar over classic array structure, which allows you to use it as classic array, but adds some cool features.

8.3.0(2y ago)10103.3k↓17.1%[1 PRs](https://github.com/MortalFlesh/MFCollectionsPHP/pulls)7MITPHPPHP ^8.2

Since Sep 14Pushed 1y ago2 watchersCompare

[ Source](https://github.com/MortalFlesh/MFCollectionsPHP)[ Packagist](https://packagist.org/packages/mf/collections-php)[ RSS](/packages/mf-collections-php/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (12)Versions (48)Used By (7)

MFCollections for PHP
=====================

[](#mfcollections-for-php)

[![Latest Stable Version](https://camo.githubusercontent.com/43fb4993770cc1bd167c23b2eb4e074f6865d59e71efe5ec82701eab37c1b310/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d662f636f6c6c656374696f6e732d7068702e737667)](https://packagist.org/packages/mf/collections-php)[![Total Downloads](https://camo.githubusercontent.com/7e58b0771aa9ead595751c91568655237883c1953dacc381d42c5980c5fcb055/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d662f636f6c6c656374696f6e732d7068702e737667)](https://packagist.org/packages/mf/collections-php)[![License](https://camo.githubusercontent.com/3825abeca6b9484d308e34e647d2ef0b04002d28a6560c80b3f663d51972ba81/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d662f636f6c6c656374696f6e732d7068702e737667)](https://packagist.org/packages/mf/collections-php)[![Tests and linting](https://github.com/MortalFlesh/MFCollectionsPHP/actions/workflows/tests.yaml/badge.svg)](https://github.com/MortalFlesh/MFCollectionsPHP/actions/workflows/tests.yaml)[![Coverage Status](https://camo.githubusercontent.com/0f8eb1d749f1da4c0ae9fd9b79a23e966c4c7f43885205fbd0515c05752cb349/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f4d6f7274616c466c6573682f4d46436f6c6c656374696f6e735048502f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/MortalFlesh/MFCollectionsPHP?branch=master)

It's basically a syntax sugar over classic array structure, which allows you to use it as classic array, but adds some cool features.

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Requirements](#requirements)
- [Base Interfaces](#base-interfaces)
    - [IEnumerable](#enumerable-interface)
    - [ICollection](#collection-interface)
    - [IList](#list-interface)
    - [IMap](#map-interface)
    - [ISeq](#seq-interface)
    - [ITuple](#tuple-interface)
- [Mutable](#mutable-collections)
- [Immutable](#immutable-collections)
- [Generic](#generic-collections)
- [Arrow Functions](#arrow-functions)
- [Plans for next versions](#plans-for-next-versions)

Installation
------------

[](#installation)

```
composer require mf/collections-php
```

Requirements
------------

[](#requirements)

- `PHP ^8.2`

Base Interfaces
---------------

[](#base-interfaces)

Check out [Documentation](https://github.com/MortalFlesh/MFCollectionsPHP/wiki) for more details.

### IEnumerable

[](#ienumerable)

- basic Interface for enumerable
- extends `IteratorAggregate`, `Countable`
- [see Immutable tuple](#immutable-tuple)
- [see Mutable PrioritizedCollection](#mutable-prioritized-collection)

### ICollection

[](#icollection)

- basic Interface for Collections
- extends `IEnumerable`
- [see Mutable collections](#mutable-collections)
- [see Immutable collections](#immutable-collections)

### IList

[](#ilist)

A *list* is an ordered (*possibly immutable*) series of elements of the same type.

- extends `ICollection`
- [see Mutable list](#mutable-list)
- [see Immutable list](#immutable-list)

### IMap

[](#imap)

A *map* is an ordered (*possibly immutable*) series of key values pairs.

- extends `ICollection, ArrayAccess`
- [see Mutable map](#mutable-map)
- [see Immutable map](#immutable-map)

### ISeq

[](#iseq)

A *sequence* is a logical series of elements all of one type.

- extends `ICollection`
- [see Immutable seq](#immutable-seq)

### ITuple

[](#ituple)

A *tuple* is a grouping of unnamed but ordered values, possibly of different types.

- extends `IEnumerable`, `ArrayAccess`, `Stringable`
- [see Immutable tuple](#immutable-tuple)

Mutable Collections
------------------------------------------------------------------

[](#mutable-collections)

### Interfaces

[](#interfaces)

- `Mutable\Generic\ICollection`, `Mutable\Generic\IList`, `Mutable\Generic\IMap`

### Mutable\\Generic\\ListCollection

[](#mutablegenericlistcollection)

- implements `Mutable\Generic\IList`
- is `eager` as possible

### Mutable\\Generic\\Map

[](#mutablegenericmap)

- implements `Mutable\Generic\IMap`
- is `eager` as possible

### Mutable\\Generic\\PrioritizedCollection

[](#mutablegenericprioritizedcollection)

- implements `IEnumerable`
- holds items with `generic` type by `priority`
- is `eager` as possible

#### Example of strategies by priority

[](#example-of-strategies-by-priority)

For case when you want to apply `only the first strategy` which can do what you want. You can add strategies `dynamically` and still apply them `by priority` later.

```
// initialization of strategies
/** @phpstan-var PrioritizedCollection $strategies */
$strategies = new PrioritizedCollection();
$strategies->add(new DefaultStrategy(), 1);

// added later
$strategies->add(new SpecialStrategy(), 100);

// find and apply first suitable strategy
/** @var StrategyInterface $strategy */
foreach ($strategies as $strategy) {
    if ($strategy->supports($somethingStrategic)) {
        return $strategy->apply($somethingStrategic);
    }
}
```

Immutable Collections
----------------------------------------------------------------------

[](#immutable-collections)

- `internal state` of Immutable\\Collection instance will `never change` from the outside (it is `readonly`)

```
$list = new Immutable\ListCollection();
$listWith1 = $list->add(1);

// $list != $listWith1
echo $list->count();        // 0
echo $listWith1->count();   // 1
```

- `$list` is still an empty `Immutable\ListCollection`
- `$listWith1` is new instance of `Immutable\ListCollection` with value `1`

### Interfaces

[](#interfaces-1)

- `Immutable\Generic\ICollection`, `Immutable\Generic\IList`, `Immutable\Generic\IMap`, `Immutable\Generic\ISeq`, `Immutable\ITuple`

### Immutable\\Generic\\ListCollection

[](#immutablegenericlistcollection)

- implements `Immutable\Generic\IList`
- is `eager` as possible

### Immutable\\Generic\\Map

[](#immutablegenericmap)

- implements `Immutable\Generic\IMap`
- is `eager` as possible

### Immutable\\Seq

[](#immutableseq)

- implements `Immutable\Generic\ISeq`
- is `lazy` as possible (*even could be `Infinite`*)

```
$seq = Seq::infinite()                         // 1, 2, ...
    ->filter(fn ($i) => $i % 2 === 0)   // 2, 4, ...
    ->skip(2)                           // 6, 8, ...
    ->map(fn ($i) => $i * $i)           // 36, 64, ...
    ->takeWhile(fn ($i) => $i < 100)    // 36, 64
    ->reverse()                         // 64, 36
    ->take(1);                          // 64
// for now the Sequence is still lazy

// this will generate (evaluate) the values
$array = $seq->toArray();               // [64]
```

### Immutable\\Generic\\KVPair

[](#immutablegenerickvpair)

- always has a `Key` and the `Value`
- key is restricted to `int|string` so it may be used in the `foreach` as a key
- can contain any values

### Immutable\\Tuple

[](#immutabletuple)

- implements `Immutable\ITuple`
- must have at least 2 values (*otherwise it is just a single value*)
- is `eager` as possible
- allows `destructuring`, `matching` and `parsing`/`formatting`
- can contain any scalar values and/or arrays
    - in string representation of a `Tuple`, array values must be separated by `;` (*not by `,`*)

#### Parsing

[](#parsing)

```
Tuple::parse('(foo, bar)')->toArray();                  // ['foo', 'bar']
Tuple::parse('("foo, bar", boo)')->toArray();           // ['foo, bar', 'boo']
Tuple::parse('(1, "foo, bar", true)')->toArray();       // [1, 'foo, bar', true]
Tuple::parse('(1, [2; 3], [four; "Five"])')->toArray(); // [1, [2, 3], ['four', 'five']]
```

#### Matching and comparing

[](#matching-and-comparing)

```
Tuple::from([1, 1])->match('int', 'int');                      // true
Tuple::from([1, 2, 3])->isSame(Tuple::of(1, 2, 3));            // true
Tuple::of(10, 'Foo', null)->match('int', 'string', '?string'); // true
Tuple::of(10, [9, 8])->match('int', 'array');                  // true
```

#### Parsing and matching

[](#parsing-and-matching)

```
Tuple::parseMatch('(foo, bar)', 'string', 'string')->toArray();        // ['foo', 'bar']
Tuple::parseMatchTypes('(foo, bar)', ['string', 'string'])->toArray(); // ['foo', 'bar']

// invalid types
Tuple::parseMatch('(foo, bar, 1)', 'string', 'string'); // throws \InvalidArgumentException "Given tuple does NOT match expected types (string, string) - got (string, string, int)"
```

#### Formatting

[](#formatting)

```
Tuple::from([1, 'foo', null])->toString();          // '(1, "foo", null)'

// for URL
Tuple::from(['foo', 'bar'])->toStringForUrl();      // '(foo,bar)'
Tuple::from(['foo-bar', 'boo'])->toStringForUrl();  // '(foo-bar,bar)'
Tuple::from(['mail', 'a@b.com'])->toStringForUrl(); // '(mail,"a@b.com")'
```

#### Destructuring

[](#destructuring)

```
$tuple  = Tuple::of('first', 2, 3); // ('first', 2, 3)
$first  = $tuple->first();          // 'first'
$second = $tuple->second();         // 2
[$first, $second] = $tuple;         // $first = 'first'; $second = 2
[,, $third]       = $tuple;         // 3
```

#### Unpacking

[](#unpacking)

```
sprintf('Title: %s | Value: %s', ...Tuple::of('foo', 'bar')); // "Title: foo | Value: bar"
```

#### Merging

[](#merging)

- merging `Tuples` will automatically flat them (*see last example below*)

```
$base  = Tuple::of('one', 'two');                       // ('one', 'two')
$upTo3 = Tuple::merge($base, 'three');                  // ('one', 'two', 'three')
$upTo4 = Tuple::merge($base, '3', 'four');              // ('one', 'two', '3', 'four')
$upTo5 = Tuple::merge($base, ['3', '4'], '5');          // ('one', 'two', ['3', '4'], '5')
$upTo5 = Tuple::merge($base, Tuple::of('3', '4'), '5'); // ('one', 'two', '3', '4', '5')
```

#### Merging and matching

[](#merging-and-matching)

```
$base = Tuple::of('one', 'two');                                    // ('one', 'two')
$upTo3 = Tuple::mergeMatch(['string', 'string', 'int'], $base, 3);  // ('one', 'two', 3)

// invalid types
Tuple::mergeMatch(['string', 'string'], $base, 3); // throws \InvalidArgumentException "Merged tuple does NOT match expected types (string, string) - got (string, string, int)."
```

Sequences and lazy mapping
--------------------------

[](#sequences-and-lazy-mapping)

- if your `Sequence` get mapped and filtered many times (*for readability*), it is not a problem
    - `map -> map -> filter -> map -> filter -> map` will iterate the collection **only once** (*for applying all modifiers at once*)
    - this modification is done when another method is triggered, so adding new modifier is an **atomic** operation
- all the values are generated on the fly, so it may end on out of memory exception

Plans for next versions
-----------------------

[](#plans-for-next-versions)

- use `Symfony/Stopwatch` in unit tests
- *even better* documentation ([current](https://github.com/MortalFlesh/MFCollectionsPHP/wiki))

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity36

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity88

Battle-tested with a long release history

 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 ~58 days

Recently: every ~4 days

Total

46

Last Release

888d ago

Major Versions

5.0.0 → 6.0.02021-03-31

v5.x-dev → 7.0.02022-04-21

7.0.0 → 8.0.02023-04-12

7.1.1 → 8.1.12023-11-25

7.2.0 → 8.2.02023-11-28

PHP version history (7 changes)1.0.0PHP &gt;=5.5 || &gt;=7.0

2.0.0PHP &gt;=7.1

4.0.0PHP &gt;=7.2

5.0.0PHP ^7.4

6.0.0PHP ^8.0

7.0.0PHP ^8.1

8.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/2bdf0b9957c08a48e70a52fce74fc4f1add30b12d442450d5e2b48854fc98b21?d=identicon)[MortalFlesh](/maintainers/MortalFlesh)

---

Top Contributors

[![MortalFlesh](https://avatars.githubusercontent.com/u/6317184?v=4)](https://github.com/MortalFlesh "MortalFlesh (257 commits)")

---

Tags

collectioncollectionsgenericgeneric-collectionsgeneric-interfaceimmutableimmutable-collectionsmutable-collectionsphpsyntax-sugar

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mf-collections-php/health.svg)

```
[![Health](https://phpackages.com/badges/mf-collections-php/health.svg)](https://phpackages.com/packages/mf-collections-php)
```

###  Alternatives

[morilog/jalali

This Package helps developers to easily work with Jalali (Shamsi or Iranian) dates in PHP applications, based on Jalali (Shamsi) DateTime class.

9201.2M45](/packages/morilog-jalali)[bruli/php-git-hooks

Git hooks for PHP projects.

675370.8k5](/packages/bruli-php-git-hooks)[nikolaposa/version

Value Object that represents a SemVer-compliant version number.

1406.4M16](/packages/nikolaposa-version)[prooph/common

Common classes used across prooph packages

852.2M27](/packages/prooph-common)[funeralzone/valueobjects

A PHP 7.1 value objects helper library.

66643.3k22](/packages/funeralzone-valueobjects)[tomasnorre/crawler

Crawler extension for TYPO3

58397.5k1](/packages/tomasnorre-crawler)

PHPackages © 2026

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