PHPackages                             cooper/hyperf-collection-macros - 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. cooper/hyperf-collection-macros

ActiveLibrary

cooper/hyperf-collection-macros
===============================

This repository contains some useful collection macros.

v0.0.2(3y ago)09MITPHPPHP &gt;=8.0

Since Aug 4Pushed 3y ago1 watchersCompare

[ Source](https://github.com/myxiaoao/hyperf-collection-macros)[ Packagist](https://packagist.org/packages/cooper/hyperf-collection-macros)[ RSS](/packages/cooper-hyperf-collection-macros/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (3)Used By (0)

A set of useful Hyperf collection macros
========================================

[](#a-set-of-useful-hyperf-collection-macros)

[ ![Tests](https://github.com/myxiaoao/hyperf-collection-macros/workflows/PHPUnit/badge.svg)](https://github.com/myxiaoao/hyperf-collection-macros/actions?query=workflow%3APHPUnit)[ ![Latest Stable Version](https://camo.githubusercontent.com/8c11c7aa3ea548b80203c6c1255738e1b38f04394644d5d758635dc2f4e1d860/68747470733a2f2f706f7365722e707567782e6f72672f636f6f7065722f6879706572662d636f6c6c656374696f6e2d6d6163726f732f762f737461626c652e737667)](https://packagist.org/packages/cooper/hyperf-collection-macros)[ ![Total Downloads](https://camo.githubusercontent.com/16538f508ba2e0b344c42b07a61ad53afcd8be60c8c43a8ef3165e7a4e99fa00/68747470733a2f2f706f7365722e707567782e6f72672f636f6f7065722f6879706572662d636f6c6c656374696f6e2d6d6163726f732f642f746f74616c2e737667)](https://packagist.org/packages/cooper/hyperf-collection-macros)This repository contains some useful collection macros.

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

[](#installation)

You can pull in the package via composer:

```
composer require cooper/hyperf-collection-macros
```

The package will automatically register itself.

Macros
------

[](#macros)

- [`after`](#after)
- [`at`](#at)
    - [`second`](#second)
    - [`third`](#third)
    - [`fourth`](#fourth)
    - [`fifth`](#fifth)
    - [`sixth`](#sixth)
    - [`seventh`](#seventh)
    - [`eighth`](#eighth)
    - [`ninth`](#ninth)
    - [`tenth`](#tenth)
    - [`getNth`](#getNth)
- [`before`](#before)
- [`catch`](#catch)
- [`chunkBy`](#chunkby)
- [`collectBy`](#collectBy)
- [`containsAny`](#containsAny)
- [`containsAll`](#containsAll)
- [`eachCons`](#eachcons)
- [`extract`](#extract)
- [`filterMap`](#filtermap)
- [`firstOrFail`](#firstorfail)
- [`firstOrPush`](#firstorpush)
- [`fromPairs`](#frompairs)
- [`glob`](#glob)
- [`groupByModel`](#groupbymodel)
- [`head`](#head)
- [`if`](#if)
- [`ifAny`](#ifany)
- [`ifEmpty`](#ifempty)
- [`insertAfter`](#insertafter)
- [`insertAfterKey`](#insertafterkey)
- [`insertAt`](#insertat)
- [`insertBefore`](#insertbefore)
- [`insertBeforeKey`](#insertbeforekey)
- [`none`](#none)
- [`path`](#path)
- [`pluckMany`](#pluckmany)
- [`pluckToArray`](#plucktoarray)
- [`prioritize`](#prioritize)
- [`recursive`](#recursive)
- [`rotate`](#rotate)
- [`sectionBy`](#sectionby)
- [`sliceBefore`](#slicebefore)
- [`tail`](#tail)
- [`toPairs`](#topairs)
- [`transpose`](#transpose)
- [`weightedRandom`](#weightedRandom)
- [`withSize`](#withsize)

### `after`

[](#after)

Get the next item from the collection.

```
$collection = collect([1,2,3]);

$currentItem = 2;

$currentItem = $collection->after($currentItem); // return 3;
$collection->after($currentItem); // return null;

$currentItem = $collection->after(function($item) {
    return $item > 1;
}); // return 3;
```

You can also pass a second parameter to be used as a fallback.

```
$collection = collect([1,2,3]);

$currentItem = 3;

$collection->after($currentItem, $collection->first()); // return 1;
```

### `at`

[](#at)

Retrieve an item at an index.

```
$data = new Collection([1, 2, 3]);

$data->at(0); // 1
$data->at(1); // 2
$data->at(-1); // 3
```

### `second`

[](#second)

Retrieve item at the second index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->second(); // 2
```

### `third`

[](#third)

Retrieve item at the third index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->third(); // 3
```

### `fourth`

[](#fourth)

Retrieve item at the fourth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->fourth(); // 4
```

### `fifth`

[](#fifth)

Retrieve item at the fifth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->fifth(); // 5
```

### `sixth`

[](#sixth)

Retrieve item at the sixth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->sixth(); // 6
```

### `seventh`

[](#seventh)

Retrieve item at the seventh index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->seventh(); // 7
```

### `eighth`

[](#eighth)

Retrieve item at the eighth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->eighth(); // 8
```

### `ninth`

[](#ninth)

Retrieve item at the ninth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->ninth(); // 9
```

### `tenth`

[](#tenth)

Retrieve item at the tenth index.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$data->tenth(); // 10
```

### `getNth`

[](#getnth)

Retrieve item at the nth item.

```
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);

$data->getNth(11); // 11
```

### `before`

[](#before)

Get the previous item from the collection.

```
$collection = collect([1,2,3]);

$currentItem = 2;

$currentItem = $collection->before($currentItem); // return 1;
$collection->before($currentItem); // return null;

$currentItem = $collection->before(function($item) {
    return $item > 2;
}); // return 2;
```

You can also pass a second parameter to be used as a fallback.

```
$collection = collect([1,2,3]);

$currentItem = 1;

$collection->before($currentItem, $collection->last()); // return 3;
```

### `catch`

[](#catch)

See [`Try`](#try)

### `chunkBy`

[](#chunkby)

Chunks the values from a collection into groups as long the given callback is true. If the optional parameter `$preserveKeys` as `true` is passed, it will preserve the original keys.

```
collect(['A', 'A', 'B', 'A'])->chunkBy(function($item) {
    return $item == 'A';
}); // return Collection([['A', 'A'],['B'], ['A']])
```

### `collectBy`

[](#collectby)

Get an item at a given key, and collect it.

```
$collection = collect([
    'foo' => [1, 2, 3],
    'bar' => [4, 5, 6],
]);

$collection->collectBy('foo'); // Collection([1, 2, 3])
```

You can also pass a second parameter to be used as a fallback.

```
$collection = collect([
    'foo' => [1, 2, 3],
    'bar' => [4, 5, 6],
]);

$collection->collectBy('baz', ['Nope']); // Collection(['Nope'])
```

### `containsAny`

[](#containsany)

Will return `true` if one or more of the given values exist in the collection.

```
$collection = collect(['a', 'b', 'c']);

$collection->containsAny(['b', 'c', 'd']); // returns true
$collection->containsAny(['c', 'd', 'e']); // returns true
$collection->containsAny(['d', 'e', 'f']); // returns false
$collection->containsAny([]); // returns false
```

### `containsAll`

[](#containsall)

Will return `true` if all given values exist in the collection.

```
$collection = collect(['a', 'b', 'c']);

$collection->containsAll(['b', 'c',]); // returns true
$collection->containsAll(['c', 'd']); // returns false
$collection->containsAll(['d', 'e']); // returns false
$collection->containsAll([]); // returns true
```

### `eachCons`

[](#eachcons)

Get the following consecutive neighbours in a collection from a given chunk size. If the optional parameter `$preserveKeys` as `true` is passed, it will preserve the original keys.

```
collect([1, 2, 3, 4])->eachCons(2); // return collect([[1, 2], [2, 3], [3, 4]])
```

### `extract`

[](#extract)

Extract keys from a collection. This is very similar to `only`, with two key differences:

- `extract` returns an array of values, not an associative array
- If a value doesn't exist, it will fill the value with `null` instead of omitting it

`extract` is useful when using PHP 7.1 short `list()` syntax.

```
[$name, $role] = collect($user)->extract('name', 'role.name');
```

### `filterMap`

[](#filtermap)

Map a collection and remove falsy values in one go.

```
$collection = collect([1, 2, 3, 4, 5, 6])->filterMap(function ($number) {
    $quotient = $number / 3;

    return is_integer($quotient) ? $quotient : null;
});

$collection->toArray(); // returns [1, 2]
```

### `firstOrFail`

[](#firstorfail)

Get the first item. Throws `Spatie\CollectionMacros\Exceptions\CollectionItemNotFound` if the item was not found.

```
$collection = collect([1, 2, 3, 4, 5, 6])->firstOrFail();

$collection->toArray(); // returns [1]

collect([])->firstOrFail(); // throws Spatie\CollectionMacros\Exceptions\CollectionItemNotFound
```

### `firstOrPush`

[](#firstorpush)

Retrieve the first item using the callable given as the first parameter. If no value exists, push the value of the second parameter into the collection. You can pass a callable as the second parameter.

This method is really useful when dealing with cached class properties, where you want to store a value retrieved from an API or computationally expensive function in a collection to be used multiple times.

```
$collection = collect([1, 2, 3])->firstOrPush(fn($item) => $item === 4, 4);

$collection->toArray(); // returns [1, 2, 3, 4]
```

Occasionally, you'll want to specify the target collection to be pushed to. You may pass this as a third parameter.

```
$collection = collect([1, 2, 3]);
$collection->filter()->firstOrPush(fn($item) => $item === 4, 4, $collection);

$collection->toArray(); // returns [1, 2, 3, 4]
```

### `fromPairs`

[](#frompairs)

Transform a collection into an associative array form collection item.

```
$collection = collect([['a', 'b'], ['c', 'd'], ['e', 'f']])->fromPairs();

$collection->toArray(); // returns ['a' => 'b', 'c' => 'd', 'e' => 'f']
```

### `glob`

[](#glob)

Returns a collection of a `glob()` result.

```
Collection::glob('config/*.php');
```

### `groupByModel`

[](#groupbymodel)

Similar to `groupBy`, but groups the collection by an Eloquent model. Since the key is an object instead of an integer or string, the results are divided into separate arrays.

```
$posts->groupByModel('category');

// [
//     [$categoryA, [/*...$posts*/]],
//     [$categoryB, [/*...$posts*/]],
// ];
```

Full signature: `groupByModel($callback, $preserveKeys, $modelKey, $itemsKey)`

### `head`

[](#head)

Retrieves first item from the collection.

```
$collection = collect([1,2,3]);

$collection->head(); // return 1

$collection = collect([]);

$collection->head(); // return null
```

### `if`

[](#if)

The `if` macro can help branch collection chains. This is the signature of this macro:

```
if(mixed $if, mixed $then = null, mixed $else = null): mixed
```

`$if`, `$then` and `$else` can be any type. If a closure is passed to any of these parameters, then that closure will be executed and the macro will use its results.

When `$if` returns a truthy value, then `$then` will be returned, otherwise `$else` will be returned.

Here are some examples:

```
collect()->if(true, then: true, else: false); // returns true
collect()->if(false, then: true, else: false); // returns false
```

When a closure is passed to `$if`, `$then` or `$else`, the entire collection will be passed as an argument to that closure.

```
// the `then` closure will be executed
// the first element of the returned collection now contains "THIS IS THE VALUE"
$collection = collect(['this is a value'])
    ->if(
        fn(Collection $collection) => $collection->contains('this is a value'),
        then: fn(Collection $collection) => $collection->map(fn(string $item) => strtoupper($item)),
        else: fn(Collection $collection) => $collection->map(fn(string $item) => Str::kebab($item))
    );

// the `else` closure will be executed
// the first element of the returned collection now contains "this-is-another-value"
$collection = collect(['this is another value'])
    ->if(
        fn(Collection $collection) => $collection->contains('this is a value'),
        then: fn(Collection $collection) => $collection->map(fn(string $item) => strtoupper($item)),
        else: fn(Collection $collection) => $collection->map(fn(string $item) => Str::kebab($item))
    );
```

### `ifAny`

[](#ifany)

Executes the passed callable if the collection isn't empty. The entire collection will be returned.

```
collect()->ifAny(function(Collection $collection) { // empty collection so this won't get called
   echo 'Hello';
});

collect([1, 2, 3])->ifAny(function(Collection $collection) { // non-empty collection so this will get called
   echo 'Hello';
});
```

### `ifEmpty`

[](#ifempty)

Executes the passed callable if the collection is empty. The entire collection will be returned.

```
collect()->ifEmpty(function(Collection $collection) { // empty collection so this will called
   echo 'Hello';
});

collect([1, 2, 3])->ifEmpty(function(Collection $collection) { // non-empty collection so this won't get called
   echo 'Hello';
});
```

### `insertAfter`

[](#insertafter)

Inserts an item after the first occurrence of a given item and returns the updated Collection instance. Optionally a key can be given.

```
collect(['zero', 'two', 'three'])->insertAfter('zero', 'one');
// Collection contains ['zero', 'one', 'two', 'three']

collect(['zero' => 0, 'two' => 2, 'three' => 3]->insertAfter(0, 5, 'five');
// Collection contains ['zero' => 0, 'five' => 5, 'two' => 2, 'three' => 3]
```

### `insertAfterKey`

[](#insertafterkey)

Inserts an item after a given key and returns the updated Collection instance. Optionally a key for the new item can be given.

```
collect(['zero', 'two', 'three'])->insertAfterKey(0, 'one');
// Collection contains ['zero', 'one', 'two', 'three']

collect(['zero' => 0, 'two' => 2, 'three' => 3]->insertAfterKey('zero', 5, 'five');
// Collection contains ['zero' => 0, 'five' => 5, 'two' => 2, 'three' => 3]
```

### `insertAt`

[](#insertat)

Inserts an item at a given index and returns the updated Collection instance. Optionally a key can be given.

```
collect(['zero', 'two', 'three'])->insertAt(1, 'one');
// Collection contains ['zero', 'one', 'two', 'three']

collect(['zero' => 0, 'two' => 2, 'three' => 3]->insertAt(1, 5, 'five');
// Collection contains ['zero' => 0, 'five' => 5, 'two' => 2, 'three' => 3]
```

### `insertBefore`

[](#insertbefore)

Inserts an item before the first occurrence of a given item and returns the updated Collection instance. Optionally a key can be given.

```
collect(['zero', 'two', 'three'])->insertBefore('two', 'one');
// Collection contains ['zero', 'one', 'two', 'three']

collect(['zero' => 0, 'two' => 2, 'three' => 3]->insertBefore(2, 5, 'five');
// Collection contains ['zero' => 0, 'five' => 5, 'two' => 2, 'three' => 3]
```

### `insertBeforeKey`

[](#insertbeforekey)

Inserts an item before a given key and returns the updated Collection instance. Optionally a key for the new item can be given.

```
collect(['zero', 'two', 'three'])->insertBeforeKey(1, 'one');
// Collection contains ['zero', 'one', 'two', 'three']

collect(['zero' => 0, 'two' => 2, 'three' => 3]->insertBeforeKey('two', 5, 'five');
// Collection contains ['zero' => 0, 'five' => 5, 'two' => 2, 'three' => 3]
```

### `none`

[](#none)

Checks whether a collection doesn't contain any occurrences of a given item, key-value pair, or passing truth test. The function accepts the same parameters as the `contains` collection method.

```
collect(['foo'])->none('bar'); // returns true
collect(['foo'])->none('foo'); // returns false

collect([['name' => 'foo']])->none('name', 'bar'); // returns true
collect([['name' => 'foo']])->none('name', 'foo'); // returns false

collect(['name' => 'foo'])->none(function ($key, $value) {
   return $key === 'name' && $value === 'bar';
}); // returns true
```

### `path`

[](#path)

Returns an item from the collection with multidimensional data using "dot" notation. Works the same way as native Collection's `pull` method, but without removing an item from the collection.

```
$collection = new Collection([
    'foo' => [
        'bar' => [
            'baz' => 'value',
        ]
    ]
]);

$collection->path('foo.bar.baz') // 'value'
```

### `pluckMany`

[](#pluckmany)

Returns a collection with only the specified keys.

```
$collection = collect([
    ['a' => 1, 'b' => 10, 'c' => 100],
    ['a' => 2, 'b' => 20, 'c' => 200],
]);

$collection->pluckMany(['a', 'b']);

// returns
// collect([
//     ['a' => 1, 'b' => 10],
//     ['a' => 2, 'b' => 20],
// ]);
```

### `pluckToArray`

[](#plucktoarray)

Returns array of values of a given key.

```
$collection = collect([
    ['a' => 1, 'b' => 10],
    ['a' => 2, 'b' => 20],
    ['a' => 3, 'b' => 30]
]);

$collection->pluckToArray('a'); // returns [1, 2, 3]
```

### `prioritize`

[](#prioritize)

Move elements to the start of the collection.

```
$collection = collect([
    ['id' => 1],
    ['id' => 2],
    ['id' => 3],
]);

$collection
   ->prioritize(function(array $item) {
      return $item['id'] === 2;
   })
   ->pluck('id')
   ->toArray(); // returns [2, 1, 3]
```

### `recursive`

[](#recursive)

Convert an array and its children to collection using recursion.

```
collect([
  'item' => [
     'children' => []
  ]
])->recursive();

// subsequent arrays are now collections
```

### `rotate`

[](#rotate)

Rotate the items in the collection with given offset

```
$collection = collect([1, 2, 3, 4, 5, 6]);

$rotate = $collection->rotate(1);

$rotate->toArray();

// [2, 3, 4, 5, 6, 1]
```

### `sectionBy`

[](#sectionby)

Splits a collection into sections grouped by a given key. Similar to `groupBy` but respects the order of the items in the collection and reuses existing keys.

```
$collection = collect([
    ['name' => 'Lesson 1', 'module' => 'Basics'],
    ['name' => 'Lesson 2', 'module' => 'Basics'],
    ['name' => 'Lesson 3', 'module' => 'Advanced'],
    ['name' => 'Lesson 4', 'module' => 'Advanced'],
    ['name' => 'Lesson 5', 'module' => 'Basics'],
]);

$collection->sectionBy('module');

// [
//     ['Basics', [
//         ['name' => 'Lesson 1', 'module' => 'Basics'],
//         ['name' => 'Lesson 2', 'module' => 'Basics'],
//     ]],
//     ['Advanced', [
//         ['name' => 'Lesson 3', 'module' => 'Advanced'],
//         ['name' => 'Lesson 4', 'module' => 'Advanced'],
//     ]],
//     ['Basics', [
//         ['name' => 'Lesson 5', 'module' => 'Basics'],
//     ]],
// ];
```

Full signature: `sectionBy($callback, $preserveKeys, $sectionKey, $itemsKey)`

### `sliceBefore`

[](#slicebefore)

Slice the values out from a collection before the given callback is true. If the optional parameter `$preserveKeys` as `true` is passed, it will preserve the original keys.

```
collect([20, 51, 10, 50, 66])->sliceBefore(function($item) {
    return $item > 50;
}); // return collect([[20],[51, 10, 50], [66])
```

### `tail`

[](#tail)

Extract the tail from a collection. So everything except the first element. It's a shorthand for `slice(1)->values()`, but nevertheless very handy. If the optional parameter `$preserveKeys` as `true` is passed, it will preserve the keys and fallback to `slice(1)`.

```
collect([1, 2, 3])->tail(); // return collect([2, 3])
```

### `toPairs`

[](#topairs)

Transform a collection into an array with pairs.

```
$collection = collect(['a' => 'b', 'c' => 'd', 'e' => 'f'])->toPairs();

$collection->toArray(); // returns ['a', 'b'], ['c', 'd'], ['e', 'f']
```

### `transpose`

[](#transpose)

The goal of transpose is to rotate a multidimensional array, turning the rows into columns and the columns into rows.

```
collect([
    ['Jane', 'Bob', 'Mary'],
    ['jane@example.com', 'bob@example.com', 'mary@example.com'],
    ['Doctor', 'Plumber', 'Dentist'],
])->transpose()->toArray();

// [
//     ['Jane', 'jane@example.com', 'Doctor'],
//     ['Bob', 'bob@example.com', 'Plumber'],
//     ['Mary', 'mary@example.com', 'Dentist'],
// ]
```

### `weightedRandom`

[](#weightedrandom)

Returns a random item by a weight. In this example, the item with `a` has the most chance to get picked, and the item with `c` the least.

```
// pass the field name that should be used as a weight

$randomItem = collect([
    ['value' => 'a', 'weight' => 30],
    ['value' => 'b', 'weight' => 20],
    ['value' => 'c', 'weight' => 10],
])->weightedRandom('weight');
```

Alternatively, you can pass a callable to get the weight.

```
$randomItem = collect([
    ['value' => 'a', 'weight' => 30],
    ['value' => 'b', 'weight' => 20],
    ['value' => 'c', 'weight' => 10],
])->weightedRandom(function(array $item) {
   return $item['weight'];
});
```

### `withSize`

[](#withsize)

Create a new collection with the specified amount of items.

```
Collection::withSize(1)->toArray(); // return [1];
Collection::withSize(5)->toArray(); // return [1,2,3,4,5];
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity43

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

Total

2

Last Release

1369d ago

### Community

Maintainers

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

---

Top Contributors

[![myxiaoao](https://avatars.githubusercontent.com/u/1223134?v=4)](https://github.com/myxiaoao "myxiaoao (6 commits)")

---

Tags

collectionhyperfphphyperf

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cooper-hyperf-collection-macros/health.svg)

```
[![Health](https://phpackages.com/badges/cooper-hyperf-collection-macros/health.svg)](https://phpackages.com/packages/cooper-hyperf-collection-macros)
```

PHPackages © 2026

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