PHPackages                             studio83/sorted-linked-list - 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. studio83/sorted-linked-list

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

studio83/sorted-linked-list
===========================

Type-safe sorted linked list for int or string values.

v1.0.0(1mo ago)00MITPHPPHP &gt;=8.2CI passing

Since May 7Pushed 1mo agoCompare

[ Source](https://github.com/wojtishek/sorted-linked-list)[ Packagist](https://packagist.org/packages/studio83/sorted-linked-list)[ RSS](/packages/studio83-sorted-linked-list/feed)WikiDiscussions main Synced 1w ago

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

studio83/sorted-linked-list
===========================

[](#studio83sorted-linked-list)

[![CI](https://github.com/wojtishek/sorted-linked-list/actions/workflows/ci.yml/badge.svg)](https://github.com/wojtishek/sorted-linked-list/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/87c492c88e1c57d9f55e8f737e6f49d65ee54b245c04f84c53591ba2abceaf55/68747470733a2f2f706f7365722e707567782e6f72672f73747564696f38332f736f727465642d6c696e6b65642d6c6973742f76)](https://packagist.org/packages/studio83/sorted-linked-list)[![PHP Version Require](https://camo.githubusercontent.com/a720415eb8a2f2174dc2d8baa36939c039c254c2edbb20a720f6e64ff3ab1d00/68747470733a2f2f706f7365722e707567782e6f72672f73747564696f38332f736f727465642d6c696e6b65642d6c6973742f726571756972652f706870)](https://packagist.org/packages/studio83/sorted-linked-list)[![License](https://camo.githubusercontent.com/cd906635bca66c25b5444812ddfaa97458d91c715965a92136de8c8015822c0c/68747470733a2f2f706f7365722e707567782e6f72672f73747564696f38332f736f727465642d6c696e6b65642d6c6973742f6c6963656e7365)](https://github.com/wojtishek/sorted-linked-list/blob/main/LICENSE)

A small, type-safe sorted singly-linked list for PHP. A single instance holds either `int` values or `string` values — never both. The constraint is enforced at the language level by exposing two distinct concrete classes.

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

[](#installation)

```
composer require studio83/sorted-linked-list
```

Requires PHP 8.2 or newer.

Usage
-----

[](#usage)

### Integers

[](#integers)

```
use Studio83\SortedLinkedList\IntSortedLinkedList;

$list = new IntSortedLinkedList(3, 1, 4, 1, 5);
$list->add(2);

$list->toArray();      // [1, 1, 2, 3, 4, 5]
$list->first();        // 1
$list->last();         // 5
$list->count();        // 6
$list->contains(4);    // true
$list->remove(1);      // true (removes ONE occurrence)
$list->toArray();      // [1, 2, 3, 4, 5]

foreach ($list as $value) {
    echo $value, "\n"; // 1, 2, 3, 4, 5
}

json_encode($list);    // "[1,2,3,4,5]"
```

### Strings

[](#strings)

```
use Studio83\SortedLinkedList\StringSortedLinkedList;

$list = StringSortedLinkedList::fromArray(['cherry', 'apple', 'banana']);
$list->toArray();      // ['apple', 'banana', 'cherry']
```

### Empty-list safety

[](#empty-list-safety)

The idiomatic guard is `isEmpty()`:

```
$list = new IntSortedLinkedList();

if (!$list->isEmpty()) {
    $head = $list->first();
}
```

If pre-checking is awkward (e.g. inside a generic helper), catch the exception:

```
use Studio83\SortedLinkedList\Exception\EmptyListException;

try {
    $head = $list->first();
} catch (EmptyListException $e) {
    // handle empty case
}
```

### Catching every library error

[](#catching-every-library-error)

```
use Studio83\SortedLinkedList\Exception\SortedLinkedListException;

try {
    IntSortedLinkedList::fromArray([1, 'not an int', 3]);
} catch (SortedLinkedListException $e) {
    // catches EmptyListException, InvalidValueException, …
}
```

API Reference
-------------

[](#api-reference)

MethodReturnsComplexityNotes`__construct(T ...$values)`—O(n²) for n insertsVariadic; supports empty initialisation`static fromArray(array $values): self`new instanceO(n²)Validates element types; throws `InvalidValueException``add(T $value): void`—O(n)Inserts at sorted position; stable for duplicates`remove(T $value): bool`boolO(n)Removes first occurrence; returns whether anything was removed`contains(T $value): bool`boolO(n) worstEarly exit when sort order overshoots`count(): int`intO(1)Maintained as a counter`isEmpty(): bool`boolO(1)`clear(): void`—O(1)`first(): T`TO(1)Throws `EmptyListException` on empty`last(): T`TO(1)Tail pointer maintained`toArray(): array``list`O(n)Zero-indexed, ascending`getIterator(): Generator`GeneratorO(1) memoryImplements `IteratorAggregate``jsonSerialize(): array``list`O(n)Implements `JsonSerializable``clone $list`new instanceO(n)Deep-copies the node chain`T` = `int` for `IntSortedLinkedList`, `string` for `StringSortedLinkedList`.

Design Decisions
----------------

[](#design-decisions)

### Why two concrete classes instead of one generic class

[](#why-two-concrete-classes-instead-of-one-generic-class)

PHP has no language-level generics. Three approaches were considered:

ApproachVerdictSingle class with PHPStan `@template` + runtime checkType errors only at runtime; PHP itself doesn't enforce.Single class with type-lock on first addLatent bug — error surfaces only on the second wrong-typed add.**Two final concrete classes + abstract parent****Chosen**. PHP enforces correctness at the language level; idiomatic Symfony pattern.### Stable insertion of duplicates

[](#stable-insertion-of-duplicates)

When inserting a value equal to one already in the list, the new element is placed **after** existing equals — insertion order is preserved among equals. This matches the standard expectation for a "sorted by key" collection.

### Explicit non-goals

[](#explicit-non-goals)

- **No custom comparator.** That's a priority queue concern; this library uses natural ordering only.
- **No configurable descending mode.** Use `array_reverse($list->toArray())`.
- **No `get(int $index)` random access.** Contradicts the linked-list nature (O(n) random access). Use `toArray()` if you need indexing.
- **No immutable `with*()` API.** Linked lists naturally fit a mutable model.
- **No unified `SortedListInterface`.** It would need `int|string` argument types (LSP), losing the type sharpness of concrete classes.

Limitations
-----------

[](#limitations)

- **String comparison is byte-wise**, not Unicode-aware. ASCII / Latin-1 sorts as expected; UTF-8 multi-byte sequences sort by byte representation. Example: `"z"  "ä"` returns `-1` (so `"z"` precedes `"ä"`). For locale-aware or Unicode-collation sorting, use `intl`'s `Collator` with a different data structure.
- **String equality is case-sensitive** (`"Foo" !== "foo"`).
- **O(n) insert and lookup.** For large collections or performance-critical paths, a balanced BST or sorted array with binary search will outperform this structure. This library prioritises clarity and a faithful "sorted linked list" implementation.
- **Modifying the list during `foreach` is undefined behaviour** (consistent with `ArrayIterator`). No fail-fast.

Development
-----------

[](#development)

```
composer install
composer test       # PHPUnit
composer analyse    # PHPStan level 9
composer fix        # PHP-CS-Fixer
composer check      # analyse + test
```

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance93

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 96.2% 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

33d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/9982805?v=4)[Vojtěch Kaizr](/maintainers/wojtishek)[@wojtishek](https://github.com/wojtishek)

---

Top Contributors

[![wojtishek](https://avatars.githubusercontent.com/u/9982805?v=4)](https://github.com/wojtishek "wojtishek (25 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

collectionlinked listsorteddata structure

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/studio83-sorted-linked-list/health.svg)

```
[![Health](https://phpackages.com/badges/studio83-sorted-linked-list/health.svg)](https://phpackages.com/packages/studio83-sorted-linked-list)
```

###  Alternatives

[phpcollection/phpcollection

General-Purpose Collection Library for PHP

96764.5M34](/packages/phpcollection-phpcollection)[league/period

Time range API for PHP

7335.7M22](/packages/league-period)[loophp/collection

A (memory) friendly, easy, lazy and modular collection class.

746730.3k15](/packages/loophp-collection)[chdemko/sorted-collections

Sorted Collections for PHP &gt;= 8.4

222.6M3](/packages/chdemko-sorted-collections)[lorisleiva/lody

Load files and classes as lazy collections in Laravel.

957.5M13](/packages/lorisleiva-lody)

PHPackages © 2026

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