PHPackages                             hadasbro/php-streams - 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. hadasbro/php-streams

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

hadasbro/php-streams
====================

PHP Streams - Java-like Stream API for PHP

1.0.4(6y ago)82.7k[3 PRs](https://github.com/hadasbro/php-stream-api/pulls)MITPHPPHP &gt;=7.4

Since Mar 11Pushed 4y ago1 watchersCompare

[ Source](https://github.com/hadasbro/php-stream-api)[ Packagist](https://packagist.org/packages/hadasbro/php-streams)[ RSS](/packages/hadasbro-php-streams/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (4)Dependencies (1)Versions (7)Used By (0)

PHP Streams
===========

[](#php-streams)

[![PHP Composer](https://github.com/hadasbro/php-stream-api/workflows/PHP%20Composer/badge.svg)](https://github.com/hadasbro/php-stream-api/workflows/PHP%20Composer/badge.svg)

[![PHP 7.4+](https://camo.githubusercontent.com/00bc8368950089b1c37a6a655228ceddd6142aaf5fa072a5b7f579956fb0dda8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253345253344253230372e342d627269676874677265656e)](https://camo.githubusercontent.com/00bc8368950089b1c37a6a655228ceddd6142aaf5fa072a5b7f579956fb0dda8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253345253344253230372e342d627269676874677265656e)[![License MIT](https://camo.githubusercontent.com/fadcec9342a1d63cf1f6c09e8e43d26a8046bf6064c5b4aefe0e33ff15423c6b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d627269676874677265656e)](https://camo.githubusercontent.com/fadcec9342a1d63cf1f6c09e8e43d26a8046bf6064c5b4aefe0e33ff15423c6b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d627269676874677265656e)[![Ver 1.0.4](https://camo.githubusercontent.com/c98c3c6456f143f810340feeb6e2839d16d7f3a2c6be485af3a81c1e78c29b3d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e302e342d626c7565)](https://camo.githubusercontent.com/c98c3c6456f143f810340feeb6e2839d16d7f3a2c6be485af3a81c1e78c29b3d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e302e342d626c7565)

This is just Collections API in PHP. Library helps to handle collections such as `arrays` or in general `iterable` elements and perform operations on them. Operations on Collection/Stream can be chained.

See usage examples in `/Examples` and unit tests in the project.

Project status: project is in progress, curent basic version is `ver 1.0.4`. Next versions will be using generators (`yield`) instead of normal looping and arrays.

Install
-------

[](#install)

Installation via Composer

```
composer require hadasbro/php-streams
```

Usage Examples
--------------

[](#usage-examples)

### Stream usage

[](#stream-usage)

#### Init / Construct options

[](#init--construct-options)

```

# Init via constructor
$stream = new CollectionsStream([1, 2, 3, 4, 5, 6, 7]);

# Init via CollectionsStream::fromIterable
$stream = CollectionsStream::fromIterable([1, 2, 3, 4, 5]);

# Init via CollectionsStream::fromStartValueAndTransformer
$stream = CollectionsStream::fromStartValueAndTransformer(1, 15, function ($value) {return $value + 1;});

# Init via CollectionsStream::fromStartValueAndTransformer - PHP 7.4 arrow functions
$stream = CollectionsStream::fromStartValueAndTransformer(1, 15, fn ($value) => $value + 1);

# Init via CollectionsStream::fromProducer
$stream = CollectionsStream::fromProducer(function () {
    $data = []; for($i = 1; $i < 20; $i++){ $data[] = $i; }; return $data;
});

# CollectionsStream::fromParams
$stream = CollectionsStream::fromParams(1, 2, 3, 4, 5);
```

#### Example of chaned operations on stream

[](#example-of-chaned-operations-on-stream)

##### Sample Object

[](#sample-object)

```
class SampleObj
{
    private int $id;
    private int $type = 1;

    public function __construct($lineId, $type = 1){
        $this->id = $lineId;
        $this->type = $type;
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function setId(int $id): self
    {
        $this->id = $id;
        return $this;
    }

    public function getType(): int
    {
        return $this->type;
    }

    public function setType(int $type): self
    {
        $this->type = $type;
        return $this;
    }

}
```

##### Example - arrow functions used for operations (PHP &gt;= 7.4)

[](#example---arrow-functions-used-for-operations-php--74)

See more [Arrow Functions PHP 7.4](https://wiki.php.net/rfc/arrow_functions)

```
class StreamTest extends TestCase
{
    public function testStream()
    {

        $manyObjects = [
            new SampleObj(0, 13),
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1),
            new SampleObj(21, 777),
            new SampleObj(0, 134),
        ];

        /**
         * @var $stream CollectionsStream
         */
        $stream = CollectionsStream::fromIterable($manyObjects);

        $reducedStream =

            $stream

            ->map(fn(SampleObj $obj) => ($obj->getType() == 13 && $obj->setType(444)) ? $obj : $obj)

            ->filter(fn(SampleObj $obj) => $obj->getId() != 1)

            ->reject(fn(SampleObj $obj) => $obj->getType() == 777)

            ->distinct(fn(SampleObj $obj1, SampleObj $obj2) => $obj1->getType() == $obj2->getType())

            ->orElse(fn(SampleObj $obj1) => $obj1->getId() == 0, new SampleObj(1, 1))

            ->sort(fn(SampleObj $obj1, SampleObj $obj2) => $obj1->getId() >= $obj2->getId())

            ->groupBy(fn(SampleObj $obj) => $obj->getType())

            ->reduce(
                fn ($acumulated, array $obj) => ($acumulated = array_merge([], is_array($acumulated) ? $acumulated : [], array_values($obj))) ? $acumulated : $acumulated
            );

        var_dump($reducedStream);
        /*
            [
                SampleObj(33, 2),
                SampleObj(7, 11),
                SampleObj(2, 1),
                SampleObj(1, 1),
                SampleObj(1, 1)
            ]
        */

    }

}
```

##### Example - lambda functions used for operations

[](#example---lambda-functions-used-for-operations)

```
class _StreamExamples
{
    public static function stream()
    {
        $manyObjects = [
            new SampleObj(0, 13),
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1),
            new SampleObj(21, 777),
            new SampleObj(0, 134),
        ];

        /**
         * @var $stream CollectionsStream
         */
        $stream = CollectionsStream::fromIterable($manyObjects);

        $stream

            # change type from 13 => 444
            ->map(function (SampleObj $obj) {
                if ($obj->getType() == 13) $obj->setType(444);
                return $obj;
            })

            # get only objects with ID != 1
            ->filter(function (SampleObj $obj) {
                return $obj->getId() != 1;
            })

            # remove objects with type = 777
            ->reject(function (SampleObj $obj) {
                return $obj->getType() == 777;
            })

            # get only unique ones (unique = with different type)
            ->distinct(function (SampleObj $obj1, SampleObj $obj2) {
                return $obj1->getType() == $obj2->getType();
            })

            # consider every object with ID = 0 as "empty"/null object we dont want
            # and replace such object to default one SampleObj(1, 1);
            ->orElse(function (SampleObj $obj1) {
                return $obj1->getId() == 0;
            }, new SampleObj(1, 1))

            # sort objects from the highest ID to the lowest
            ->sort(function (SampleObj $obj1, SampleObj $obj2) {
                return $obj1->getId() >= $obj2->getId();
            })

            # group our collection by object's type
            # after groupping in the stream we will have array like below one
            # [2 => [ SampleObj(33, 2) ], 11 => [ SampleObj(7, 11)]]
            ->groupBy(function (SampleObj $obj) {
                return $obj->getType();
            });

        # now we can e.g. transform that array of elements back
        # to simple list of objects by using reducer
        # [ SampleObj(33, 2), SampleObj(7, 11) ...]

        $reducedStream = $stream
            ->reduce(function ($acumulated, array $obj) {
                $acumulated ??= [];
                $acumulated = array_merge($acumulated, array_values($obj));
                return $acumulated;
            });

        var_dump($reducedStream);
        /*
            [
                SampleObj(33, 2),
                SampleObj(7, 11),
                SampleObj(2, 1),
                SampleObj(1, 1),
                SampleObj(1, 1)
            ]
        */

        # we can also reduce it to e.g. concatenation of those objects' IDs
        $reducedToIds = $stream

            ->reduce(function ($acumulated, $obj) {

                $acumulated ??= '';

                foreach ($obj as $item) {
                    $acumulated .= ',' . strval($item->getId());
                }

                return ltrim($acumulated, ',');
            });

        var_dump($reducedToIds); // 33,7,2,1,1

    }

}
```

### Raw examples, static usage - lambda functions used for operations

[](#raw-examples-static-usage---lambda-functions-used-for-operations)

##### Example of `Collections::collect` (predefined collectors)

[](#example-of-collectionscollect-predefined-collectors)

Examples:

```
class _CollectorsExamples
{

    public static function generalTest() {

        try {

            $manyObjects = [
                new SampleObj(1, 13),
                new SampleObj(14, 13),
                new SampleObj(7, 11),
                new SampleObj(14, 13),
                new SampleObj(33, 2),
                new SampleObj(33, 11),
                new SampleObj(2, 1)
            ];

            # join all IDs into 1 string separated by commas
            $collector = Collector::of(Collector::JOINING, function (CollectionsSampleObject $obj) { return $obj->getId(); });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected); // '1,14,7,14,33,33,2'

            # Join with custom separator - @
            $collector = Collector::of(Collector::JOINING, function (CollectionsSampleObject $obj) { return ['value' => $obj->getId(), 'separator' => '@']; });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected); // 1@14@7@14@33@33@2

            # sum all elements
            $collector = Collector::of(Collector::SUMMING, function (SampleObj $obj) { return $obj->getId(); });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // 104

            # multiply all elements
            $collector = Collector::of(Collector::MULTIPLYING, function (SampleObj $obj) { return $obj->getId(); });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // 2 988 216

            # put all elements to array
            $collector = Collector::of(Collector::TO_FLAT_ARRAY, function (SampleObj $obj) { return $obj->getId(); });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // [ 1, 14, 7, 14, 33, 33, 2 ]

            # return string with all alements wrapped by single quote
            $collector = Collector::of(Collector::TO_CONCAT_OF_STRINGS, function (SampleObj $obj) { return $obj->getId(); });
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // '1','14','7','14','33','33','2'

            # generate and return associative array of elements
            $collector = Collector::of(Collector::TO_ASSOC_ARRAY, function (SampleObj $obj) {
                # here, in extractor, we need to define how do we want to
                # generate key and value for each element
                return ['key' => $obj->getType(), 'value' => $obj];
            });

            $collected = Collections::collect($manyObjects, $collector);

            va($collected);
            /*
                [
                    13 => new SampleObj(14, 13),
                    11 => new SampleObj(33, 11),
                    2 => new SampleObj(2, 2)
                    1 => new SampleObj(2, 1)
                ]
            */

        } catch (\Throwable $t) {
            vae($t);
        }

    }

}
```

Predefined collectors

```
class Collector extends CollectorOperations {

    const JOINING = 1; # [a, b, c] -> a,b,c
    const SUMMING = 2; # [a, b, c] -> a + b + c
    const MULTIPLYING = 3; # [a, b, c] -> a * b * c
    const TO_FLAT_ARRAY = 4; # [obj1, obj2, obj3] -> [ obj1->getId(), obj2->getId(), obj3->getId()]
    const TO_CONCAT_OF_STRINGS = 5; # [obj1, obj2] -> ['{obj1->getId()}', '{obj2->getId()}']

    /*
     * Note: if you use this collector, then your extractor must
     * specify how do you want to generate keys and values from your data
     * Your extractor must return [key => _how_to_obtain_key_, value => _how_to_obtain_value_ ]
     *
     * for example:
     *
     *      $collector = Collector::of(
     *          Collector::TO_ASSOC_ARRAY,
     *          function ($obj) { return ['key' => $obj->getId(), 'value' => $obj]; }
     *      );
     *
     */
    const TO_ASSOC_ARRAY = 6; # [obj1, obj2] -> [obj1->getId() => obj1, obj2->getId() => obj2]
}
```

##### Example of `Collections::allMatch` (all objects from our array are also in another array)

[](#example-of-collectionsallmatch-all-objects-from-our-array-are-also-in-another-array)

```
class _AllMatchExamples
{
    public static function allMatch()
    {
        $manyObjects = [1, 2, 3, 4, 5];
        $objects = [21, 17, 1, 2, 3, 4, 5, 666];

        $allMatch = Collections::allMatch($manyObjects, function (int $obj1) use ($objects) {
            # predicate method should return TRUE if we consider element as
            # matching to our criteria or FALSE if element doesnt match
            return in_array($obj1, $objects);
        });

        var_dump($allMatch); // true

    }
}
```

##### Example of `Collections::distinct` (get only objects with different IDs)

[](#example-of-collectionsdistinct-get-only-objects-with-different-ids)

```
class _CollectionsExamples
{
    public static function distinct()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(14),
            new SampleObj(33),
            new SampleObj(33),
        ];

        $unique = Collections::distinct($manyObjects, function (SampleObj $obj1, SampleObj $obj2) {
            # comparator should return TRUE if $obj1 is equal $obj2
            # or FALSE if we consider $obj1 and $obj2 as unequal
            # this is in terms of any criteria we want to apply
            return $obj1->getId() == $obj2->getId();
        });

        var_dump($unique); # [ SampleObj(14),  SampleObj(7),  SampleObj(33), ]

    }

}
```

##### Example of `Collections::filter` (get only objects with the ID &lt; 11)

[](#example-of-collectionsfilter-get-only-objects-with-the-id--11)

```
class _FilterExamples
{
    public static function filter()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $filteredResult = Collections::filter($manyObjects, function (SampleObj $obj) {
            return $obj->getId() < 11;
        });

        var_dump($filteredResult); #   [ SampleObj(7), SampleObj(1) ]

    }
}
```

##### Example of `Collections::reject` (remove objects with ID &lt; 11)

[](#example-of-collectionsreject-remove-objects-with-id--11)

```
class _RejectExamples
{
    public static function reject()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $filteredResult = Collections::reject($manyObjects, function (SampleObj $obj) {
            return $obj->getId() < 11;
        });

        var_dump($filteredResult); # [ SampleObj(14), SampleObj(33) ]

    }

}
```

##### Example of `Collections::map`, `Collections::transform` (modify every objeect's ID to be + 100)

[](#example-of-collectionsmap-collectionstransform-modify-every-objeects-id-to-be--100)

```
class _MapExamples
{
    public static function map()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7)
        ];

        $mappedResult = Collections::map($manyObjects, function (SampleObj $obj) {
            $obj->setId($obj->getId() + 100);
            return $obj;
        });

        var_dump($mappedResult); #   [ SampleObj(114), SampleObj(107) ]

    }

}
```

##### Example of `Collections::minMax` (get object with the lowest ID)

[](#example-of-collectionsminmax-get-object-with-the-lowest-id)

```
class _MinMaxExamples
{
    public static function minMax()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $minElement = Collections::min($manyObjects, function (SampleObj $obj1, SampleObj $obj2) {
            # comparator should return TRUE if $obj1 < $obj2
            # in terms of any criteria we want to apply
            return $obj1->getId() < $obj2->getId();
        });

        var_dump($minElement); # new SampleObj(1),
        var_dump($minElement->getId()); # 1

    }

}
```

##### Example of Collections::sort (sort collection of objects to start from objects with the lowest ID)

[](#example-of-collectionssort-sort-collection-of-objects-to-start-from-objects-with-the-lowest-id)

```
class _SortExamples
{
    public static function sort()
    {
        $manyObjects = [
            new SampleObj(1),
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(14),
            new SampleObj(33),
            new SampleObj(33),
            new SampleObj(2)
        ];

        # order ASC (from the smallest object's IDs)
        $sortedCollection = Collections::sort($manyObjects, function (SampleObj $obj1, SampleObj $obj2) {
            # sorter should return TRUE if $obj1 is < $obj2, so if we expect order [$obj1, $obj2]
            # or oposite - FALSE - if we expect order [$obj1, $obj2]
            # this is in terms of any criteria we want to apply
            return $obj1->getId() < $obj2->getId();
        });

        var_dump($sortedCollection);
        /*
            [
                new SampleObj(1),
                new SampleObj(2),
                new SampleObj(7),
                new SampleObj(14),
            ]
        */

    }
}
```

##### Example of `Collections::orElse` (get collection with objects but replace each one with ID &lt;= 0 to default one)

[](#example-of-collectionsorelse-get-collection-with-objects-but-replace-each-one-with-id--0-to-default-one)

```
class _OrElseExamples
{
    public static function orElse()
    {
        $manyObjects = [
            new SampleObj(0),
            new SampleObj(14),
            new SampleObj(-1),
            new SampleObj(14),
            new SampleObj(-22)
        ];

        # order ASCE (from the smallest object's IDs)
        $collection = Collections::orElse($manyObjects, function (SampleObj $obj1) {
            # return TRUE if we consider that particular object as "NULL" in any meaning
            # (if we want to replace that kind of object to any other - default one)
            # here - every object with ID getId() getId();
            return $ids;
        });

        var_dump($reduced);
        /* ["ID#0","ID#14","ID#-1", "ID#14", "ID#-22"] */

    }
}
```

##### Example of `Collections::groupBy` (group objects by type)

[](#example-of-collectionsgroupby-group-objects-by-type)

```
class _GroupByExamples
{
    public static function group()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        # normal count
        $groupped = Collections::groupBy(
            $manyObjects,
            function (SampleObj $obj) {
                return $obj->getType();
            }
        );

        var_dump($groupped);
        /*
            [
                13 => [SampleObj(1, 13), SampleObj(14, 13), SampleObj(14, 13)],
                11 => [SampleObj(7, 11), SampleObj(33, 11)],
                2 => [SampleObj(33, 2)],
                1 => [SampleObj(2, 1)]
            ]
        */

    }

}
```

##### Example of `Collections::countBy` and `Collections::count` (group objects by type)

[](#example-of-collectionscountby-and-collectionscount-group-objects-by-type)

```
class _CountExamples
{
    public static function countBy()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        # normal count
        $count = Collections::count($manyObjects);
        var_dump($count); # 7

        # count with groupping by object's type
        $counted = Collections::countBy(
            $manyObjects,
            function (SampleObj $obj) {
                return $obj->getType();
            }
        );

        var_dump($counted);
        /*
        [
            13 => 3
            11 => 2
            2 => 1
            1 => 1
        ]
        */

    }

}
```

##### Example of `Collections::contains` and `Collections::search` (search elements in a collection or just check if collection contains element)

[](#example-of-collectionscontains-and-collectionssearch-search-elements-in-a-collection-or-just-check-if-collection-contains-element)

```
class _ContainsSearch
{
    public static function contains()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        $contains = Collections::contains($manyObjects, function (SampleObj $obj1) {
            return $obj1->getId() == 14;
        });

        $contains2 = Collections::contains($manyObjects, function (SampleObj $obj1) {
            return $obj1->getId() == 144;
        });

        $search = Collections::search($manyObjects, function (SampleObj $obj1) {
            return $obj1->getId() == 144;
        });

        $search2 = Collections::search($manyObjects, function (SampleObj $obj1) {
            return $obj1->getType() == 13;
        });

        var_dump($contains); // true
        var_dump($contains2); // false
        var_dump($search); // []
        var_dump($search2); // [ SampleObj(1, 13), SampleObj(14, 13), SampleObj(14, 13) ]

    }

}
```

##### Example of `Collections::forEach` (consuming collection's elements)

[](#example-of-collectionsforeach-consuming-collections-elements)

```
class _ForeachExamples
{
    public static function foreach()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        Collections::forEach($manyObjects, function (SampleObj $obj1) {
            echo ' We just want to pring object ID whic is # ' . $obj1->getId() . PHP_EOL;
        });

        /*
            We just want to pring object ID whic is # 1
            We just want to pring object ID whic is # 14
            We just want to pring object ID whic is # 7
            We just want to pring object ID whic is # 14
            We just want to pring object ID whic is # 33
            We just want to pring object ID whic is # 33
            We just want to pring object ID whic is # 2
      */

    }

}
```

##### Example of `Collections::toAssocArray` (transform collection to associative array of elements)

[](#example-of-collectionstoassocarray-transform-collection-to-associative-array-of-elements)

```
class _ToArrayAssocExamples
{
    public static function toAssocArray()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        try{
            # stict - dont tolerate dupplicated keys
            $assocArray = Collections::toAssocArray($manyObjects, function (SampleObj $obj1) {
                return $obj1->getType();
            });
            /*
                 CollectionsInvalidInputException
                'Not unique key in Collections::toAssocArray.
                Strict mode require every key to be unique.
                Please verify your keyProducer.'
            */
        }catch (\Throwable $t) {}

        # non strict - take the latest value in case of dupplicated key
        $assocArray = Collections::toAssocArray($manyObjects, function (SampleObj $obj1) {
            return $obj1->getType();
        }, false);
        /*
            [
                14 => SampleObj(14, 13),
                11 => SampleObj(33, 2),
                2 => SampleObj(2, 33),
                1 => SampleObj(2, 1)
            ]
        */

        # Assoc array as a source - return the same array (because we have assoc array already)
        $assocArray = Collections::toAssocArray(['a' => 1, 'b' => 2], function ($obj1) {
            # this is gonna be ignored because we already have
            # assoc array, so we dont modify current keys and values
            return 123;
        }, false);
        /*
            ['a' => 1, 'b' => 2]
        */

    }

}
```

##### Other examples - `Collections::isEmpty`, `Collections::isNotEmpty` and others

[](#other-examples---collectionsisempty-collectionsisnotempty-and-others)

```
class _OtherMethodsExamples
{
    public static function test()
    {

        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $empty = Collections::isEmpty($manyObjects);
        $notEmpty = Collections::isNotEmpty($manyObjects);

        var_dump([$empty, $notEmpty]); #   [ true, false ]

    }

}
```

### Raw examples, static usage - arrow functions used for operations (PHP &gt;= 7.4)

[](#raw-examples-static-usage---arrow-functions-used-for-operations-php--74)

##### Example of `Collections::allMatch`, `Collections::aanyMatch` (all objects from our array are also in another array)

[](#example-of-collectionsallmatch-collectionsaanymatch-all-objects-from-our-array-are-also-in-another-array)

```
class _AllMatchExamples
{

    public static function allMatch()
    {

        $manyObjects = [1, 2, 3, 4, 5];
        $objects = [21, 17, 1, 2, 3, 4, 5, 666];

        /**
         * @var $allMatch bool
         */
        $allMatch = Collections::allMatch($manyObjects, fn(int $obj1) => in_array($obj1, $objects));

        var_dump($allMatch); // true

    }

    public static function anyMatch(){

        $manyObjects = [1, 2, 3, 4, 5];
        $objects = [21, 17];

        /**
         * @var $anyMatch bool
         */
        $anyMatch = Collections::anyMatch($manyObjects, fn(int $obj1) => in_array($obj1, $objects));

        var_dump($anyMatch); // false
    }

}
```

##### Example of `Collections::filter` (get only objects with the ID &lt; 11)

[](#example-of-collectionsfilter-get-only-objects-with-the-id--11-1)

```
class _FilterExamples
{

    public static function filter()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $filteredResult = Collections::filter($manyObjects, fn(SampleObj $obj) => $obj->getId() < 11);

        var_dump($filteredResult); #   [ SampleObj(7), SampleObj(1) ]

    }
}
```

##### Example of `Collections::reject` (remove objects with ID &lt; 11)

[](#example-of-collectionsreject-remove-objects-with-id--11-1)

```
class _RejectExamples
{

    public static function reject()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        $filteredResult = Collections::reject($manyObjects, fn (SampleObj $obj) => $obj->getId() < 11);

        var_dump($filteredResult); #   [ SampleObj(14), SampleObj(33) ]

    }

}
```

##### Example of `Collections::map`, `Collections::transform` (modify every objeect's ID to be + 100)

[](#example-of-collectionsmap-collectionstransform-modify-every-objeects-id-to-be--100-1)

```
class _MapExamples
{

    public static function map()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7)
        ];

        $mappedResult = Collections::map($manyObjects, fn(SampleObj $obj) => $obj->setId($obj->getId() + 100) && $obj ? $obj : $obj);

        var_dump($mappedResult); #   [ SampleObj(114), SampleObj(107) ]

    }

}
```

##### Example of `Collections::minMax` (get object with the lowest ID)

[](#example-of-collectionsminmax-get-object-with-the-lowest-id-1)

```
class _MinMaxExamples
{

    public static function minMax()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(1),
            new SampleObj(33)
        ];

        /**
         * @var $minElement SampleObj
         */
        $minElement = Collections::min($manyObjects, fn(SampleObj $obj1, SampleObj $obj2) => $obj1->getId() < $obj2->getId());

        var_dump($minElement); # new SampleObj(1),

    }

}
```

##### Example of `Collections::distinct` (get only objects with different IDs)

[](#example-of-collectionsdistinct-get-only-objects-with-different-ids-1)

```
class _DistinctExamples
{

    public static function distinct()
    {
        $manyObjects = [
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(14),
            new SampleObj(33),
            new SampleObj(33),
        ];

        /**
         * @var $unique SampleObj[]
         */
        $unique = Collections::distinct($manyObjects, fn(SampleObj $obj1, SampleObj $obj2) => $obj1->getId() == $obj2->getId());

        var_dump($unique); # [ SampleObj(14),  SampleObj(7),  SampleObj(33), ]

    }

}
```

##### Example of Collections::sort (sort collection of objects to start from objects with the lowest ID)

[](#example-of-collectionssort-sort-collection-of-objects-to-start-from-objects-with-the-lowest-id-1)

```
class _SortExamples
{

    public static function sort()
    {
        $manyObjects = [
            new SampleObj(1),
            new SampleObj(14),
            new SampleObj(7),
            new SampleObj(14),
            new SampleObj(33),
            new SampleObj(33),
            new SampleObj(2)
        ];

        # order ASCE (from the smallest object's IDs)
        $sortedCollection = Collections::sort($manyObjects, fn (SampleObj $obj1, SampleObj $obj2) => $obj1->getId() < $obj2->getId());

        var_dump($sortedCollection);
        /*
            [
                new SampleObj(1),
                new SampleObj(2),
                new SampleObj(7),
                new SampleObj(14)
            ]
        */

    }
}
```

##### Example of `Collections::orElse` (get collection with objects but replace each one with ID &lt;= 0 to default one)

[](#example-of-collectionsorelse-get-collection-with-objects-but-replace-each-one-with-id--0-to-default-one-1)

```
class _OrElseExamples
{

    public static function orElse()
    {
        $manyObjects = [
            new SampleObj(0),
            new SampleObj(14),
            new SampleObj(-1),
            new SampleObj(14),
            new SampleObj(-22)
        ];

        # order ASCE (from the smallest object's IDs)
        $collection = Collections::orElse($manyObjects, fn(SampleObj $obj1) => $obj1->getId()  ($concatOfStrings .= $str) ? $concatOfStrings : $concatOfStrings);

        var_dump($reduced); //aaabbabcbb

    }
}
```

##### Example of `Collections::groupBy` (group objects by type)

[](#example-of-collectionsgroupby-group-objects-by-type-1)

```
class _GroupByExamples
{

    public static function group()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        # normal count
        $groupped = Collections::groupBy(
            $manyObjects,
            fn (SampleObj $obj) => $obj->getType()
        );

        var_dump($groupped);
        /*
            [
                13 => [SampleObj(1, 13), SampleObj(14, 13), SampleObj(14, 13)],
                11 => [SampleObj(7, 11), SampleObj(33, 11)],
                2 => [SampleObj(33, 2)],
                1 => [SampleObj(2, 1)]
            ]
        */

    }

}
```

##### Example of `Collections::contains` and `Collections::search` (search elements in a collection or just check if collection contains element)

[](#example-of-collectionscontains-and-collectionssearch-search-elements-in-a-collection-or-just-check-if-collection-contains-element-1)

```
class _ContainsSearch
{

    public static function contains()
    {
        $manyObjects = [
            new SampleObj(1, 13),
            new SampleObj(14, 13),
            new SampleObj(7, 11),
            new SampleObj(14, 13),
            new SampleObj(33, 2),
            new SampleObj(33, 11),
            new SampleObj(2, 1)
        ];

        $contains = Collections::contains($manyObjects, fn(SampleObj $obj1) => $obj1->getId() == 14);

        var_dump($contains); // true

    }

}
```

##### Example of `Collections::collect` (predefined collectors)

[](#example-of-collectionscollect-predefined-collectors-1)

Examples:

```
class _CollectorsExamples
{

    public static function generalTest() {

        try {

            $manyObjects = [
                new SampleObj(1, 13),
                new SampleObj(14, 13),
                new SampleObj(7, 11),
                new SampleObj(14, 13),
                new SampleObj(33, 2),
                new SampleObj(33, 11),
                new SampleObj(2, 1)
            ];

            # join all IDs into 1 string separated by commas
            $collector = Collector::of(Collector::JOINING, fn (CollectionsSampleObject $obj) => $obj->getId());
            $collected = Collections::collect($manyObjects, $collector);
            va($collected); // '1,14,7,14,33,33,2'

            # Join with custom separator - @
            $collector = Collector::of(Collector::JOINING, fn (CollectionsSampleObject $obj) => ['value' => $obj->getId(), 'separator' => '@']);
            $collected = Collections::collect($manyObjects, $collector);
            va($collected); // 1@14@7@14@33@33@2

            # sum all elements
            $collector = Collector::of(Collector::SUMMING, fn (CollectionsSampleObject $obj) => $obj->getId());
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // 104

            # multiply all elements
            $collector = Collector::of(Collector::MULTIPLYING, fn (CollectionsSampleObject $obj) =>  $obj->getId());
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // 2 988 216

            # put all elements to array
            $collector = Collector::of(Collector::TO_FLAT_ARRAY, fn (CollectionsSampleObject $obj) => $obj->getId());
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // [ 1, 14, 7, 14, 33, 33, 2 ]

            # return string with all alements wrapped by single quote
            $collector = Collector::of(Collector::TO_CONCAT_OF_STRINGS, fn (CollectionsSampleObject $obj) => $obj->getId());
            $collected = Collections::collect($manyObjects, $collector);
            va($collected);  // '1','14','7','14','33','33','2'

            # generate and return associative array of elements
            $collector = Collector::of(Collector::TO_ASSOC_ARRAY, fn (CollectionsSampleObject $obj) => ['key' => $obj->getType(), 'value' => $obj]);
            $collected = Collections::collect($manyObjects, $collector);

            va($collected);
            /*
                [
                    13 => new SampleObj(14, 13),
                    11 => new SampleObj(33, 11),
                    2 => new SampleObj(2, 2)
                    1 => new SampleObj(2, 1)
                ]
            */

        } catch (\Throwable $t) {
            vae($t);
        }

    }

}
```

---

### Contract for stream methods (non static ones)

[](#contract-for-stream-methods-non-static-ones)

Below interface show full contract of all stream methods can be used.

```
interface CollectionsContextApi
{

    # map elements in the collection to any other elements or just transforrm
    public function map(callable $mapper): self ;

    # filter elements in the collection
    public function filter(callable $predicate): self;

    # alias to filter
    public function transform(callable $predicate): self;

    # remove only elements matching to predicate
    public function reject(callable $predicate): self;

    # get the smallest/lowest/youngest element
    public function min(callable $firstIsLowerComparator);

    # get the biggest/highest/oldest element
    public function max(callable $firstIsLowerComparator);

    # check if collection is empty
    public function isEmpty(): bool;

    # check if collection is not empty
    public function isNotEmpty(): bool;

    # sort colelction
    public function sort(callable $biSorter): self;

    # count elements in the collection
    public function count() : int;

    # count elements and group by provided keys
    public function countBy(callable $keyProducer): array;

    # reduce collection into 1 element
    public function reduce(callable $reducer);

    # get distinct sub-collection
    public function distinct(callable $biPredicate): self;

    # check if all elements match to criteria
    public function allMatch(callable $predicate): bool;

    # check if any elements match to criteria
    public function anyMatch(callable $predicate): bool;

    # check if every element doesnt match to criteria
    public function noneMatch(callable $predicate): bool;

    # get sub-collection groupped by required criteria
    public function groupBy(callable $keyProducer): self ;

    # get sub-collection with all "not-null elements", every "null-element" replace to default element
    # "null element" is an element which match to predicate
    public function orElse(callable $isNullPredicate, $defaultElement): self;

    # get sub-collection with all "not-null elements" or throw an Exception if any "null element" is inside
    public function orElseThrow(callable $isNullPredicate): self;

    # check if collection contains element
    public function contains(callable $predicate): bool;

    # search element in the collection
    public function search(callable $predicate): self;

    # call function on each element from collection (consume collection's elements)
    public function forEach(callable $consumer): void;

    # tansform colection to associative array with required keys (keys are produced by keyProducer)
    public function toAssocArray(callable $keyProducer, $strict = true): self;

    # get current collection (after all modifications). This is alias for self::getCollection
    public function get(): iterable;

    # get current collection (after all modifications)
    public function getCollection(): iterable;

    # flat elements [FUTURE
    public function flatMap(callable $flatterFunction): self;

    # collect to any required data structure
    public function collect(Collector $collector);

    # add element to collection
    public function append($element): self;

    # add element to at the beginning of collection
    public function prepend($element): self;

    # shuffle collection
    public function shuffle(): self;

    # skip x - elements in a collection
    public function skip(int $skipElements): self;

    # take only x - elements from collection
    public function limit(int $limit): self ;

    # reverse collection
    public function reverse(): self;

}
```

---

### Contract for static methods

[](#contract-for-static-methods)

Below interface show full contract of all static methods can be used.

```
interface CollectionsStaticApi {

    # map elements in the collection to any other elements or just transforrm
    public static function map(iterable $source, callable $mapper): array;

    # filter elements in the collection
    public static function filter(iterable $source, callable $predicate): array;

    # alias to filter
    public static function transform(iterable $source, callable $predicate): array;

    # remove only elements matching to predicate
    public static function reject(iterable $source, callable $predicate): array;

    # get the smallest/lowest/youngest element
    public static function min(iterable $source, callable $firstIsLowerComparator);

    # get the biggest/highest/oldest element
    public static function max(iterable $source, callable $firstIsLowerComparator);

    # check if collection is empty
    public static function isEmpty(iterable $source): bool;

    # check if collection is not empty
    public static function isNotEmpty(iterable $source): bool;

    # sort colelction
    public static function sort(iterable $source, callable $biSorter): array;

    # count elements in the collection
    public static function count(iterable $source) : int;

    # count elements and group by provided keys
    public static function countBy(iterable $source, callable $keyProducer): array;

    # reduce collection into 1 element
    public static function reduce(iterable $source, callable $reducer);

    # get distinct sub-collection
    public static function distinct(iterable $source, callable $biPredicate): array;

    # check if all elements match to criteria
    public static function allMatch(iterable $source, callable $predicate): bool;

    # check if any elements match to criteria
    public static function anyMatch(iterable $source, callable $predicate): bool;

    # check if every element doesnt match to criteria
    public static function noneMatch(iterable $source, callable $predicate): bool;

    # get sub-collection groupped by required criteria
    public static function groupBy(iterable $source, callable $keyProducer): array;

    # get sub-collection with all "not-null elements", every "null-element" replace to default element
    # "null element" is an element which match to predicate
    public static function orElse(iterable $source, callable $isNullPredicate, $defaultElement): array;

    # get sub-collection with all "not-null elements" or throw an Exception if any "null element" is inside
    public static function orElseThrow(iterable $source, callable $isNullPredicate): array;

    # check if collection contains element
    public static function contains(iterable $source, callable $predicate): bool;

    # search element in the collection
    public static function search(iterable $source, callable $predicate): array;

    # call function on each element from collection (consume collection's elements)
    public static function forEach(iterable $source, callable $consumer): void;

    # tansform colection to associative array with required keys (keys are produced by keyProducer)
    public static function toAssocArray(iterable $source, callable $keyProducer, $strict = true): array;

    # flat elements [FUTURE]
    public static function flatMap(iterable $source, callable $flatterFunction): array;

    # collect to any required data structure
    public static function collect(iterable $source, Collector $collector);

    # add element to collection
    public static function append(iterable $source, $element): array;

    # add element to at the beginning of collection
    public function prepend($element): self;

    # shuffle collection
    public static function shuffle(iterable $source): array;

    # skip x - elements in a collection
    public static function skip(iterable $source, int $skipElements): array;

    # take only x - elements from collection
    public static function limit(iterable $source, int $limit): array;

    # reverse collection
    public static function reverse(iterable $source): array;

}
```

### Informations

[](#informations)

Curently library needs PHP &gt;= 7.4. Soon it will be redesigned to support also older versions of PHP.

Author - Slawomir Hadas

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity25

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity61

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

Total

3

Last Release

2289d ago

### Community

Maintainers

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

---

Top Contributors

[![hadasbro](https://avatars.githubusercontent.com/u/8734471?v=4)](https://github.com/hadasbro "hadasbro (16 commits)")

###  Code Quality

TestsCodeception

### Embed Badge

![Health badge](/badges/hadasbro-php-streams/health.svg)

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

###  Alternatives

[eightynine/filament-reports

Elegant reports in your filament application

10036.1k](/packages/eightynine-filament-reports)

PHPackages © 2026

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