PHPackages                             kllakk/yalinqo - 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. kllakk/yalinqo

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

kllakk/yalinqo
==============

YaLinqo, a LINQ-to-objects library for PHP

v2.4.2(7y ago)08BSD-2-ClausePHPPHP &gt;=5.5

Since Feb 25Pushed 4y agoCompare

[ Source](https://github.com/kllakk/YaLinqo)[ Packagist](https://packagist.org/packages/kllakk/yalinqo)[ Docs](http://athari.github.io/YaLinqo)[ RSS](/packages/kllakk-yalinqo/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (3)Versions (17)Used By (0)

*YaLinqo: Yet Another LINQ to Objects for PHP*
==============================================

[](#yalinqo-yet-another-linq-to-objects-for-php)

[![Travis CI Status](https://camo.githubusercontent.com/a5b452b66937dd16adbbe78eeed0e955cd02e1ced03f0c5de596873b243ab0ff/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f4174686172692f59614c696e716f2e737667)](https://travis-ci.org/Athari/YaLinqo)[![Coveralls Coverage](https://camo.githubusercontent.com/72148b38fa1b781de68d64a4787ca94832a7e9184c62da61eb4c0b3e24508230/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f4174686172692f59614c696e716f2f6d61737465722e737667)](https://coveralls.io/r/Athari/YaLinqo)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/0610760c19827899f59bd46d2ffce5c75574afc24e0f3013d9ef3c8788e2c406/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f4174686172692f59614c696e716f2e737667)](https://scrutinizer-ci.com/g/Athari/YaLinqo)[![SensioLabs Insight Check](https://camo.githubusercontent.com/c73e97ffe6aa3ed182c26336eb4fce313c4529a68e9a6340aafac03225cdf10f/68747470733a2f2f696d672e736869656c64732e696f2f73656e73696f6c6162732f692f64313237336638362d383565332d343037362d613033372d6134303036323930363332392e737667)](https://insight.sensiolabs.com/projects/d1273f86-85e3-4076-a037-a40062906329)[![VersionEye Dependencies](https://camo.githubusercontent.com/fffe63e2a6dc5f52dd6222f26fca85c7623a286ecb614bb55f9692f7ef01bb74/68747470733a2f2f7777772e76657273696f6e6579652e636f6d2f7068702f6174686172693a79616c696e716f2f62616467652e737667)](https://www.versioneye.com/php/athari:yalinqo)
[![Packagist Downloads](https://camo.githubusercontent.com/57c9ce38de9c64f0e1f0ccb7df82c660b5966be4e32871a00c0e610a9617ea89/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6174686172692f79616c696e716f2e737667)](https://packagist.org/packages/athari/yalinqo)[![VersionEye References](https://camo.githubusercontent.com/5b940be72d9cc59d533a9d89bf100f5b672a53d75c3127a801c6abc2bf0fa398/68747470733a2f2f7777772e76657273696f6e6579652e636f6d2f7068702f6174686172693a79616c696e716f2f7265666572656e63655f62616467652e737667)](https://www.versioneye.com/php/athari:yalinqo/references)[![Packagist Version](https://camo.githubusercontent.com/04c8954a8a6307b494dbfab89c945663e930e8331039737e65fc87c431c783f7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6174686172692f79616c696e716f2e737667)](https://packagist.org/packages/athari/yalinqo)[![GitHub License](https://camo.githubusercontent.com/516497dc683bbb49e34d802b0619bd5b1d2723c49b6aca64863c9cf45ed1d593/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4174686172692f59614c696e716f2e737667)](license.md)

- [**Online documentation**](http://athari.github.io/YaLinqo)
- [**GitHub repository**](https://github.com/Athari/YaLinqo)

Features
========

[](#features)

- The most complete port of .NET LINQ to PHP, with [many additional methods](#implemented-methods).
- Lazy evaluation, error messages and other behavior of original LINQ.
- [Detailed PHPDoc and online reference](http://athari.github.io/YaLinqo) based on PHPDoc for all methods. Articles are adapted from original LINQ documentation from MSDN.
- 100% unit test coverage.
- Best performance among full-featured LINQ ports (YaLinqo, Ginq, Pinq), at least 2x faster than the closest competitor, see [performance tests](https://github.com/Athari/YaLinqoPerf).
- Callback functions can be specified as closures (like `function ($v) { return $v; }`), PHP "function pointers" (either strings like `'strnatcmp'` or arrays like `array($object, 'methodName')`), string "lambdas" using various syntaxes (`'"$k = $v"'`, `'$v ==> $v+1'`, `'($v, $k) ==> $v + $k'`, `'($v, $k) ==> { return $v + $k; }'`).
- Keys are as important as values. Most callback functions receive both values and the keys; transformations can be applied to both values and the keys; keys are never lost during transformations, if possible.
- SPL interfaces `Iterator`, `IteratorAggregate` etc. are used throughout the code and can be used interchangeably with Enumerable.
- Redundant collection classes are avoided, native PHP arrays are used everywhere.
- Composer support ([package](https://packagist.org/packages/athari/yalinqo) on Packagist).
- No external dependencies.

Implemented methods
===================

[](#implemented-methods)

Some methods had to be renamed, because their names are reserved keywords. Original methods names are given in parenthesis.

- **Generation**: cycle, emptyEnum (empty), from, generate, toInfinity, toNegativeInfinity, matches, returnEnum (return), range, rangeDown, rangeTo, repeat, split;
- **Projection and filtering**: cast, ofType, select, selectMany, where;
- **Ordering**: orderBy, orderByDescending, orderByDir, thenBy, thenByDescending, thenByDir;
- **Joining and grouping**: groupJoin, join, groupBy;
- **Aggregation**: aggregate, aggregateOrDefault, average, count, max, maxBy, min, minBy, sum;
- **Set**: all, any, append, concat, contains, distinct, except, intersect, prepend, union;
- **Pagination**: elementAt, elementAtOrDefault, first, firstOrDefault, firstOrFallback, last, lastOrDefault, lastOrFallback, single, singleOrDefault, singleOrFallback, indexOf, lastIndexOf, findIndex, findLastIndex, skip, skipWhile, take, takeWhile;
- **Conversion**: toArray, toArrayDeep, toList, toListDeep, toDictionary, toJSON, toLookup, toKeys, toValues, toObject, toString;
- **Actions**: call (do), each (forEach), write, writeLine.

In total, more than 80 methods.

Example
=======

[](#example)

*Process sample data:*

```
// Data
$products = array(
    array('name' => 'Keyboard',    'catId' => 'hw', 'quantity' =>  10, 'id' => 1),
    array('name' => 'Mouse',       'catId' => 'hw', 'quantity' =>  20, 'id' => 2),
    array('name' => 'Monitor',     'catId' => 'hw', 'quantity' =>   0, 'id' => 3),
    array('name' => 'Joystick',    'catId' => 'hw', 'quantity' =>  15, 'id' => 4),
    array('name' => 'CPU',         'catId' => 'hw', 'quantity' =>  15, 'id' => 5),
    array('name' => 'Motherboard', 'catId' => 'hw', 'quantity' =>  11, 'id' => 6),
    array('name' => 'Windows',     'catId' => 'os', 'quantity' => 666, 'id' => 7),
    array('name' => 'Linux',       'catId' => 'os', 'quantity' => 666, 'id' => 8),
    array('name' => 'Mac',         'catId' => 'os', 'quantity' => 666, 'id' => 9),
);
$categories = array(
    array('name' => 'Hardware',          'id' => 'hw'),
    array('name' => 'Operating systems', 'id' => 'os'),
);

// Put products with non-zero quantity into matching categories;
// sort categories by name;
// sort products within categories by quantity descending, then by name.
$result = from($categories)
    ->orderBy('$cat ==> $cat["name"]')
    ->groupJoin(
        from($products)
            ->where('$prod ==> $prod["quantity"] > 0')
            ->orderByDescending('$prod ==> $prod["quantity"]')
            ->thenBy('$prod ==> $prod["name"]'),
        '$cat ==> $cat["id"]', '$prod ==> $prod["catId"]',
        '($cat, $prods) ==> array(
            "name" => $cat["name"],
            "products" => $prods
        )'
    );

// Alternative shorter syntax using default variable names
$result2 = from($categories)
    ->orderBy('$v["name"]')
    ->groupJoin(
        from($products)
            ->where('$v["quantity"] > 0')
            ->orderByDescending('$v["quantity"]')
            ->thenBy('$v["name"]'),
        '$v["id"]', '$v["catId"]',
        'array(
            "name" => $v["name"],
            "products" => $e
        )'
    );

// Closure syntax, maximum support in IDEs, but verbose and hard to read
$result3 = from($categories)
    ->orderBy(function ($cat) { return $cat['name']; })
    ->groupJoin(
        from($products)
            ->where(function ($prod) { return $prod["quantity"] > 0; })
            ->orderByDescending(function ($prod) { return $prod["quantity"]; })
            ->thenBy(function ($prod) { return $prod["name"]; }),
        function ($cat) { return $cat["id"]; },
        function ($prod) { return $prod["catId"]; },
        function ($cat, $prods) {
            return array(
                "name" => $cat["name"],
                "products" => $prods
            );
        }
    );

print_r($result->toArrayDeep());
```

*Output (compacted):*

```
Array (
    [hw] => Array (
        [name] => Hardware
        [products] => Array (
            [0] => Array ( [name] => Mouse       [catId] => hw [quantity] =>  20 [id] => 2 )
            [1] => Array ( [name] => CPU         [catId] => hw [quantity] =>  15 [id] => 5 )
            [2] => Array ( [name] => Joystick    [catId] => hw [quantity] =>  15 [id] => 4 )
            [3] => Array ( [name] => Motherboard [catId] => hw [quantity] =>  11 [id] => 6 )
            [4] => Array ( [name] => Keyboard    [catId] => hw [quantity] =>  10 [id] => 1 )
        )
    )
    [os] => Array (
        [name] => Operating systems
        [products] => Array (
            [0] => Array ( [name] => Linux       [catId] => os [quantity] => 666 [id] => 8 )
            [1] => Array ( [name] => Mac         [catId] => os [quantity] => 666 [id] => 9 )
            [2] => Array ( [name] => Windows     [catId] => os [quantity] => 666 [id] => 7 )
        )
    )
)

```

Requirements
============

[](#requirements)

- Version 1 (stable): PHP 5.3 or higher.
- Version 2 (stable): PHP 5.5 or higher.
- Version 3 (pre-alpha): PHP 7.0 or higher.

Usage
=====

[](#usage)

Add to `composer.json`:

```
{
    "require": {
        "athari/yalinqo": "^2.0"
    }
}
```

Add to your PHP script:

```
require_once 'vendor/autoloader.php';
use \YaLinqo\Enumerable;

// 'from' can be called as a static method or via a global function shortcut
Enumerable::from(array(1, 2, 3));
from(array(1, 2, 3));
```

License
=======

[](#license)

[**Simplified BSD License**](license.md)
Copyright © 2012–2018, Alexander Prokhorov
All rights reserved.

Links
=====

[](#links)

### YaLinqo Articles

[](#yalinqo-articles)

- **CodeProject** *(English):*

    - [LINQ for PHP comparison: YaLinqo, Ginq, Pinq](http://www.codeproject.com/Articles/997238/LINQ-for-PHP-comparison-YaLinqo-Ginq-Pinq) — performance comparison of full-featured LINQ ports, with some additional information.
- **Habrahabr** *(Russian):*

    - [Comparison of old LINQ libraries](http://habrahabr.ru/post/147612/) — comparison of *LINQ for PHP*, *Phinq*, *PHPLinq* and *Plinq*, also *Underscore.php*.
    - [YaLinqo 1.0 with updated comparison](http://habrahabr.ru/post/147848/) — explanation of architecture and design decisions.
    - [YaLinqo 2.0](http://habrahabr.ru/post/229763/) — switch to PHP 5.5 with generators support and related changes.
    - [LINQ for PHP: speed matters](http://habrahabr.ru/post/259155/) — performance comparison of full-featured LINQ ports (YaLinqo, Ginq, Pinq).
- **Other** *(English):*

    - Tute Wall: [How to use Linq in PHP](http://tutewall.com/how-to-use-linq-in-php-part-01/) by *Mr. X* — a series of posts covering basic usage of YaLinqo.

### Related projects

[](#related-projects)

- [**linq.js**](http://linqjs.codeplex.com/) — LINQ for JavaScript. The one and only complete port of .NET LINQ to JavaScript.
- [**Underscore.js**](http://documentcloud.github.com/underscore/) — library for functional programming in JavaScript. Similar to LINQ, but different method names and no lazy evaluation.
- [**Underscore.php**](http://brianhaveri.github.com/Underscore.php/) — port of Underscore.js to PHP.
- [**RxPHP**](https://github.com/ReactiveX/RxPHP) — reactive (push) counterpart of the active (pull) LINQ, port of Rx.NET.
- [**YaLinqoPerf**](https://github.com/Athari/YaLinqoPerf) — collection of performance tests comparing raw PHP, array functions, YaLinqo, YaLinqo with string lambdas, Ginq, Ginq with property accessors, Pinq.

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 86.8% 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 ~143 days

Recently: every ~80 days

Total

16

Last Release

2677d ago

Major Versions

v1.0.1.1 → v2.0.0.02014-07-12

v1.1.0.0 → v2.3.0.02015-06-07

v1.1.1 → v2.4.12018-02-25

v1.1.2 → v2.4.22019-01-10

PHP version history (2 changes)v1.0.0.0PHP &gt;=5.3

v2.0.0.0PHP &gt;=5.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/01ad161d1be9b708600805937774ac9649c1521da25d5e3c66e6ad79fbdf2b8e?d=identicon)[kllakk](/maintainers/kllakk)

---

Top Contributors

[![Athari](https://avatars.githubusercontent.com/u/1715107?v=4)](https://github.com/Athari "Athari (145 commits)")[![sanmai](https://avatars.githubusercontent.com/u/139488?v=4)](https://github.com/sanmai "sanmai (17 commits)")[![zquintana](https://avatars.githubusercontent.com/u/130444?v=4)](https://github.com/zquintana "zquintana (3 commits)")[![lucasjsoliveira](https://avatars.githubusercontent.com/u/9120016?v=4)](https://github.com/lucasjsoliveira "lucasjsoliveira (1 commits)")[![spetrov-4xxi](https://avatars.githubusercontent.com/u/96622495?v=4)](https://github.com/spetrov-4xxi "spetrov-4xxi (1 commits)")

---

Tags

querystatisticlinqlinqo

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kllakk-yalinqo/health.svg)

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

###  Alternatives

[athari/yalinqo

YaLinqo, a LINQ-to-objects library for PHP

4561.2M5](/packages/athari-yalinqo)[league/uri-components

URI components manipulation library

31932.3M67](/packages/league-uri-components)[ginq/ginq

LINQ to Object inspired DSL for PHP

192257.5k3](/packages/ginq-ginq)[nahid/qarray

QArray is a PHP abstraction for querying array

108403.2k2](/packages/nahid-qarray)[rpnzl/arrch

Array queries for PHP 5.3

37134.6k2](/packages/rpnzl-arrch)[jasny/dotkey

Dot notation access for objects and arrays

14219.5k6](/packages/jasny-dotkey)

PHPackages © 2026

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