PHPackages                             adhocore/underscore - 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. adhocore/underscore

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

adhocore/underscore
===================

PHP underscore inspired &amp;amp;/or cloned from \_.js

v1.0.0(3y ago)435.1k6MITPHPPHP &gt;=8.0CI passing

Since Nov 9Pushed 3y ago1 watchersCompare

[ Source](https://github.com/adhocore/php-underscore)[ Packagist](https://packagist.org/packages/adhocore/underscore)[ Fund](https://paypal.me/ji10)[ GitHub Sponsors](https://github.com/adhocore)[ RSS](/packages/adhocore-underscore/feed)WikiDiscussions main Synced 3d ago

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

adhocore/underscore
-------------------

[](#adhocoreunderscore)

PHP underscore inspired &amp;/or cloned from awesome `_.js`. A set of utilities and data manipulation helpers providing convenience functionalites to deal with array, list, hash, functions and so on in a neat elegant and OOP way. Guaranteed to save you tons of boiler plate codes when churning complex data collection.

[![Latest Version](https://camo.githubusercontent.com/310c4271035ffb097a97d0bcbf4778673225b0e18aef769a161162bb30e1697a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6164686f636f72652f7068702d756e64657273636f72652e7376673f7374796c653d666c61742d737175617265)](https://github.com/adhocore/php-underscore/releases)[![Travis Build](https://camo.githubusercontent.com/904bc39fbbcaa0146d2160cb4bd5b8c0bb896099f191f9e90f5e8ded9521e52a/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6164686f636f72652f7068702d756e64657273636f72652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/adhocore/php-underscore?branch=master)[![Scrutinizer CI](https://camo.githubusercontent.com/d95084d5ab5ff240a8e2f877461a5696c069e82727289dfd9e0870fa6f1ea917/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f6164686f636f72652f7068702d756e64657273636f72652e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/adhocore/php-underscore/?branch=master)[![Codecov branch](https://camo.githubusercontent.com/5956cd221ebb75a93c2d7f7dc6e09b0087dacc20e0764e32425fd200f0ddf710/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f6164686f636f72652f7068702d756e64657273636f72652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/gh/adhocore/php-underscore)[![StyleCI](https://camo.githubusercontent.com/ece829e4ffce4bf7578b44be8fa26b3387cdbbbed84e9987cca3d28daa47f328/68747470733a2f2f7374796c6563692e696f2f7265706f732f3130383433373033382f736869656c64)](https://styleci.io/repos/108437038)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Tweet](https://camo.githubusercontent.com/cb820a0ecc9645168e33b03925d7f14691262ddbaeaf66a0a91697803d0cba2d/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f75726c2f687474702f736869656c64732e696f2e7376673f7374796c653d736f6369616c)](https://twitter.com/intent/tweet?text=Functional+programming+paradigm+in+PHP+to+manipulate+arrays+like+pro&url=https://github.com/adhocore/php-underscore&hashtags=php,functional,array,collection)[![Support](https://camo.githubusercontent.com/6687993dc9b60228356720a501b7c197c8c9a82194cac1b1c72d0dea95e6ad32/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d537570706f7274266d6573736167653d254532253944254134266c6f676f3d476974487562)](https://github.com/sponsors/adhocore)

- Zero dependency (no vendor bloat).

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

[](#installation)

Requires PHP5.6 or later.

```
composer require adhocore/underscore
```

Usage and API
-------------

[](#usage-and-api)

Although all of them are available with helper function `underscore($data)` or `new Ahc\Underscore($data)`, the methods are grouped and organized in different heriarchy and classes according as their scope. This keeps it maintainable and saves from having a God class.

#### Contents

[](#contents)

- [Underscore](#underscore)
- [UnderscoreFunction](#underscorefunction)
- [UnderscoreArray](#underscorearray)
- [UnderscoreCollection](#underscorecollection)
- [UnderscoreBase](#underscorebase)
- [HigherOrderMessage](#higherordermessage)
- [ArrayAccess](#arrayaccess)
- [Arrayizes](#arrayizes)

---

### Underscore

[](#underscore)

#### constant(mixed $value): callable

[](#constantmixed-value-callable)

Generates a function that always returns a constant value.

```
$fn = underscore()->constant([1, 2]);

$fn(); // [1, 2]
```

#### noop(): void

[](#noop-void)

No operation!

```
underscore()->noop(); // void/null
```

#### random(int $min, int $max): int

[](#randomint-min-int-max-int)

Return a random integer between min and max (inclusive).

```
$rand = underscore()->random(1, 10);
```

#### times(int $n, callable $fn): self

[](#timesint-n-callable-fn-self)

Run callable n times and create new collection.

```
$fn = function ($i) { return $i * 2; };

underscore()->times(5, $fn)->get();
// [0, 2, 4, 6, 8]
```

#### uniqueId(string $prefix): string

[](#uniqueidstring-prefix-string)

Generate unique ID (unique for current go/session).

```
$u  = underscore()->uniqueId();      // '1'
$u1 = underscore()->uniqueId();      // '2'
$u3 = underscore()->uniqueId('id:'); // 'id:3'
```

---

### UnderscoreFunction

[](#underscorefunction)

#### compose(callable $fn1, callable $fn2, ...callable|null $fn3): mixed

[](#composecallable-fn1-callable-fn2-callablenull-fn3-mixed)

Returns a function that is the composition of a list of functions, each consuming the return value of the function that follows.

```
$c = underscore()->compose('strlen', 'strtolower', 'strtoupper');

$c('aBc.xYz'); // ABC.XYZ => abc.xyz => 7
```

#### delay(callable $fn, int $wait): mixed

[](#delaycallable-fn-int-wait-mixed)

Cache the result of callback for given arguments and reuse that in subsequent call.

```
$cb = underscore()->delay(function () { echo 'OK'; }, 100);

// waits 100ms
$cb(); // 'OK'
```

#### memoize(callable $fn): mixed

[](#memoizecallable-fn-mixed)

Returns a callable which when invoked caches the result for given arguments and reuses that result in subsequent calls.

```
$sum = underscore()->memoize(function ($a, $b) { return $a + $b; });

$sum(4, 5); // 9

// Uses memo:
$sum(4, 5); // 9
```

#### throttle(callable $fn, int $wait): mixed

[](#throttlecallable-fn-int-wait-mixed)

Returns a callable that wraps given callable which can be only invoked at most once per given $wait threshold.

```
$fn = underscore()->throttle($callback, 100);

while (...) {
    $fn(); // it will be constantly called but not executed more than one in 100ms

    if (...) break;
}
```

---

### UnderscoreArray

[](#underscorearray)

#### compact(): self

[](#compact-self)

Get only the truthy items.

```
underscore($array)->compact()->get();
// [1 => 'a', 4 => 2, 5 => [1]
```

#### difference(array|mixed $data): self

[](#differencearraymixed-data-self)

Get the items whose value is not in given data.

```
underscore([1, 2, 1, 'a' => 3, 'b' => [4]])->difference([1, [4]])->get();
// [1 => 2, 'a' => 3]
```

#### findIndex(callable $fn): mixed|null

[](#findindexcallable-fn-mixednull)

Find the first index that passes given truth test.

```
$u = underscore([[1, 2], 'a' => 3, 'x' => 4, 'y' => 2, 'b' => 'B']);

$isEven = function ($i) { return is_numeric($i) && $i % 2 === 0; };

$u->findIndex();        // 0
$u->findIndex($isEven); // 'x'
```

#### findLastIndex(callable $fn): mixed|null

[](#findlastindexcallable-fn-mixednull)

Find the last index that passes given truth test.

```
$u = underscore([[1, 2], 'a' => 3, 'x' => 4, 'y' => 2, 'b' => 'B']);

$isEven = function ($i) { return is_numeric($i) && $i % 2 === 0; };

$u->findLastIndex();        // 'b'
$u->findLastIndex($isEven); // 'y'
```

#### first(int $n): array|mixed

[](#firstint-n-arraymixed)

Get the first n items.

```
underscore([1, 2, 3])->first(); // 1
underscore([1, 2, 3])->first(2); // [1, 2]
```

#### flatten(): self

[](#flatten-self)

Gets the flattened version of multidimensional items.

```
$u = underscore([0, 'a', '', [[1, [2]]], 'b', [[[3]], 4, 'c', underscore([5, 'd'])]]);

$u->flatten()->get(); // [0, 'a', '', 1, 2, 'b', 3, 4, 'c', 5, 'd']
```

#### indexOf(mixed $value): string|int|null

[](#indexofmixed-value-stringintnull)

Find the first index of given value if available null otherwise.

```
$u = underscore([[1, 2], 'a' => 2, 'x' => 4]);

$array->indexOf(2); // 'a'
```

#### intersection(array|mixed $data): self

[](#intersectionarraymixed-data-self)

Gets the items whose value is common with given data.

```
$u = underscore([1, 2, 'a' => 3]);

$u->intersection([2, 'a' => 3, 3])->get(); // [1 => 2, 'a' => 3]
```

#### last(int $n): array|mixed

[](#lastint-n-arraymixed)

Get the last n items.

```
underscore([1, 2, 3])->last();   // 3
underscore([1, 2, 3])->last(2);  // [2, 3]
```

#### lastIndexOf(mixed $value): string|int|null

[](#lastindexofmixed-value-stringintnull)

Find the last index of given value if available null otherwise.

```
$u = underscore([[1, 2], 'a' => 2, 'x' => 4, 'y' => 2]);

$array->lastIndexOf(2); // 'y'
```

#### object(string|null $className): self

[](#objectstringnull-classname-self)

Hydrate the items into given class or stdClass.

```
underscore(['a', 'b' => 2])->object(); // stdClass(0: 'a', 'b': 2)
```

#### range(int $start, int $stop, int $step): self

[](#rangeint-start-int-stop-int-step-self)

Creates a new range from start to stop with given step.

```
underscore()->range(4, 9)->get(); // [4, 5, 6, 7, 8, 9]
```

#### sortedIndex(mixed $object, callable|string $fn): string|int|null

[](#sortedindexmixed-object-callablestring-fn-stringintnull)

Gets the smallest index at which an object should be inserted so as to maintain order.

```
underscore([1, 3, 5, 8, 11])->sortedIndex(9, null); // 4
```

#### union(array|mixed $data): self

[](#unionarraymixed-data-self)

Get the union/merger of items with given data.

```
$u = underscore([1, 2, 'a' => 3]);

$u->union([3, 'a' => 4, 'b' => [5]])->get(); // [1, 2, 'a' => 4, 3, 'b' => [5]]
```

#### unique(callable|string $fn): self

[](#uniquecallablestring-fn-self)

Gets the unique items using the id resulted from callback.

```
$u = underscore([1, 2, 'a' => 3]);

$u->union([3, 'a' => 4, 'b' => [5]])->get();
// [1, 2, 'a' => 4, 3, 'b' => [5]]
```

#### zip(array|mixed $data): self

[](#ziparraymixed-data-self)

Group the values from data and items having same indexes together.

```
$u = underscore([1, 2, 'a' => 3, 'b' => 'B']);

$u->zip([2, 4, 'a' => 5])->get();
// [[1, 2], [2, 4], 'a' => [3, 5], 'b' => ['B', null]]
```

---

### UnderscoreCollection

[](#underscorecollection)

#### contains(mixed $item): bool

[](#containsmixed-item-bool)

Check if the collection contains given item.

```
$u = underscore(['a' => 1, 'b' => 2, 'c' => 3, 5]);

$u->contains(1);   // true
$u->contains('x'); // false
```

#### countBy(callable|string $fn): self

[](#countbycallablestring-fn-self)

Count items in each group indexed by the result of callback.

```
$u = underscore([
    ['a' => 0, 'b' => 1, 'c' => 1],
    ['a' => true, 'b' => false, 'c' => 'c'],
    ['a' => 2, 'b' => 1, 'c' => 2],
    ['a' => 1, 'b' => null, 'c' => 0],
]);

// by key 'a'
$u->countBy('a')->get();
// [0 => 1, 1 => 2, 2 => 1]
```

#### each(callable $fn): self

[](#eachcallable-fn-self)

Apply given callback to each of the items in collection.

```
$answers = [];
underscore([1, 2, 3])->each(function ($num) use (&$answers) {
    $answers[] = $num * 5;
});

$answers; // [5, 10, 15]
```

#### every(callable $fn): bool

[](#everycallable-fn-bool)

Tests if all the items pass given truth test.

```
$gt0 = underscore([1, 2, 3, 4])->every(function ($num) { return $num > 0; });

$gt0; // true
```

#### filter(callable|string|null $fn): self

[](#filtercallablestringnull-fn-self)

Find and return all the items that passes given truth test.

```
$gt2 = underscore([1, 2, 4, 0, 3])->filter(function ($num) { return $num > 2; });

$gt2->values(); // [4, 3]
```

#### find(callable $fn, bool $useValue): mixed|null

[](#findcallable-fn-bool-usevalue-mixednull)

Find the first item (or index) that passes given truth test.

```
$num = underscore([1, 2, 4, 3])->find(function ($num) { return $num > 2; });

$num; // 4

$idx = underscore([1, 2, 4, 3])->find(function ($num) { return $num > 2; }, false);

$idx; // 2
```

#### findWhere(array $props): mixed

[](#findwherearray-props-mixed)

Get the first item that contains all the given props (matching both index and value).

```
$u = underscore([['a' => 1, 'b' => 2], ['a' => 2, 'b' => 2], ['a' => 1, 'b' => 3]]);

$u->findWhere(['b' => 3]); // ['a' => 1, 'b' => 3]
```

#### groupBy(callable|string $fn): self

[](#groupbycallablestring-fn-self)

Group items by using the result of callback as index. The items in group will have original index intact.

```
$u = underscore([
    ['a' => 0, 'b' => 1, 'c' => 1],
    ['a' => true, 'b' => false, 'c' => 'c'],
    ['a' => 2, 'b' => 1, 'c' => 2],
    ['a' => 1, 'b' => null, 'c' => 0],
]);

// by key 'a'
$u->groupBy('a')->get();
// [
//  0 => [0 => ['a' => 0, 'b' => 1, 'c' => 1]],
//  1 => [1 => ['a' => true, 'b' => false, 'c' => 'c'], 3 => ['a' => 1, 'b' => null, 'c' => 0]],
//  2 => [2 => ['a' => 2, 'b' => 1, 'c' => 2]],
// ]
```

#### indexBy(callable|string $fn): self

[](#indexbycallablestring-fn-self)

Reindex items by using the result of callback as new index.

```
$u = underscore([
    ['a' => 0, 'b' => 1, 'c' => 1],
    ['a' => true, 'b' => false, 'c' => 'c'],
    ['a' => 2, 'b' => 1, 'c' => 2],
    ['a' => 1, 'b' => null, 'c' => 0],
]);

// by key 'a'
$u->indexBy('a')->get();
// [
//   0 => ['a' => 0, 'b' => 1, 'c' => 1],
//   1 => ['a' => 1, 'b' => null, 'c' => 0],
//   2 => ['a' => 2, 'b' => 1, 'c' => 2],
// ]
```

#### invoke(callable $fn): mixed

[](#invokecallable-fn-mixed)

Invoke a callback using all of the items as arguments.

```
$sum = underscore([1, 2, 4])->invoke(function () { return array_sum(func_get_args()); });

$sum; // 7
```

#### map(callable $fn): self

[](#mapcallable-fn-self)

Update the value of each items with the result of given callback.

```
$map = underscore([1, 2, 3])->map(function ($num) { return $num * 2; });

$map->get(); // [2, 4, 6]
```

#### max(callable|string|null $fn): mixed

[](#maxcallablestringnull-fn-mixed)

Find the maximum value using given callback or just items.

```
underscore([1, 5, 4])->max(); // 5
$u = underscore([['a' => 1, 'b' => 2], ['a' => 2, 'b' => 3], ['a' => 0, 'b' => 1]]);

$u->max(function ($i) { return $i['a'] + $i['b']; }); // 5
```

#### min(callable|string|null $fn): mixed

[](#mincallablestringnull-fn-mixed)

Find the minimum value using given callback or just items.

```
underscore([1, 5, 4])->min(); // 1
$u = underscore([['a' => 1, 'b' => 2], ['a' => 2, 'b' => 3], ['a' => 0, 'b' => 1]]);

$u->min(function ($i) { return $i['a'] + $i['b']; }); // 1
```

#### partition(callable|string $fn): self

[](#partitioncallablestring-fn-self)

Separate the items into two groups: one passing given truth test and other failing.

```
$u = underscore(range(1, 10));

$oddEvn = $u->partition(function ($i) { return $i % 2; });

$oddEvn->get(0); // [1, 3, 5, 7, 9]
$oddEvn->get(1); // [2, 4, 6, 8, 10]
```

#### pluck(string|int $columnKey, string|int $indexKey): self

[](#pluckstringint-columnkey-stringint-indexkey-self)

Pluck given property from each of the items.

```
$u = underscore([['name' => 'moe', 'age' => 30], ['name' => 'curly']]);

$u->pluck('name')->get(); // ['moe', 'curly']
```

#### reduce(callable $fn, mixed $memo): mixed

[](#reducecallable-fn-mixed-memo-mixed)

Iteratively reduce the array to a single value using a callback function.

```
$sum = underscore([1, 2, 3])->reduce(function ($sum, $num) {
    return $num + $sum;
}, 0);

$sum; // 6
```

#### reduceRight(callable $fn, mixed $memo): mixed

[](#reducerightcallable-fn-mixed-memo-mixed)

Same as reduce but applies the callback from right most item first.

```
$concat = underscore([1, 2, 3, 4])->reduceRight(function ($concat, $num) {
    return $concat . $num;
}, '');

echo $concat; // '4321'
```

#### reject(callable $fn): self

[](#rejectcallable-fn-self)

Find and return all the items that fails given truth test.

```
$evens = underscore([1, 2, 3, 4, 5, 7, 6])->reject(function ($num) {
    return $num % 2 !== 0;
});

$evens->values(); // [2, 4, 6]
```

#### sample(int $n): self

[](#sampleint-n-self)

Get upto n items in random order.

```
$u = underscore([1, 2, 3, 4]);

$u->sample(1)->count(); // 1
$u->sample(2)->count(); // 2
```

#### shuffle(): self

[](#shuffle-self)

Randomize the items keeping the indexes intact.

```
underscore([1, 2, 3, 4])->shuffle()->get();
```

#### some(callable $fn): bool

[](#somecallable-fn-bool)

Tests if some (at least one) of the items pass given truth test.

```
$some = underscore([1, 2, 0, 4, -1])->some(function ($num) {
    return $num > 0;
});

$some; // true
```

#### sortBy(callable $fn): self

[](#sortbycallable-fn-self)

Sort items by given callback and maintain indexes.

```
$u = underscore(range(1, 15))->shuffle(); // randomize
$u->sortBy(null)->get(); // [1, 2, ... 15]

$u = underscore([['a' => 1, 'b' => 2], ['a' => 2, 'b' => 3], ['a' => 0, 'b' => 1]]);
$u->sortBy('a')->get();
// [2 => ['a' => 0, 'b' => 1], 0 => ['a' => 1, 'b' => 2], 1 => ['a' => 2, 'b' => 3]]

$u->sortBy(function ($i) { return $i['a'] + $i['b']; })->get();
// [2 => ['a' => 0, 'b' => 1], 0 => ['a' => 1, 'b' => 2], 1 => ['a' => 2, 'b' => 3]],
```

#### where(array $props): self

[](#wherearray-props-self)

Filter only the items that contain all the given props (matching both index and value).

```
$u = underscore([['a' => 1, 'b' => 2], ['a' => 2, 'b' => 2], ['a' => 1, 'b' => 3, 'c']]);

$u->where(['a' => 1, 'b' => 2])->get(); // [['a' => 1, 'b' => 2, 'c']]
```

---

### UnderscoreBase

[](#underscorebase)

#### `_`(array|mixed $data): self

[](#_arraymixed-data-self)

A static shortcut to constructor.

```
$u = Ahc\Underscore\Underscore::_([1, 3, 7]);
```

#### `__`toString(): string

[](#__tostring-string)

Stringify the underscore instance as json string.

```
echo (string) underscore([1, 2, 3]); // [1, 2, 3]
echo (string) underscore(['a', 2, 'c' => 3]); // {0: "a", 1: 2, "c":3}
```

#### asArray(mixed $data, bool $cast): array

[](#asarraymixed-data-bool-cast-array)

Get data as array.

```
underscore()->asArray('one');                        // ['one']
underscore()->asArray([1, 2]);                       // [1, 2]
underscore()->asArray(underscore(['a', 1, 'c', 3])); // ['a', 1, 'c', 3]

underscore()->asArray(new class {
    public function toArray()
    {
        return ['a', 'b', 'c'];
    }
}); // ['a', 'b', 'c']

underscore()->asArray(new class implements \JsonSerializable {
    public function jsonSerialize()
    {
        return ['a' => 1, 'b' => 2, 'c' => 3];
    }
}); // ['a' => 1, 'b' => 2, 'c' => 3]
```

#### clon(): self

[](#clon-self)

Creates a shallow copy of itself.

```
$u = underscore(['will', 'be', 'cloned']);

$u->clon() ==  $u; // true
$u->clon() === $u; // false
```

#### count(): int

[](#count-int)

Gets the count of items.

```
underscore([1, 2, [3, 4]])->count(); // 3
underscore()->count();               // 0
```

#### flat(array $array): array

[](#flatarray-array-array)

Flatten a multi dimension array to 1 dimension.

```
underscore()->flat([1, 2, [3, 4, [5, 6]]]); // [1, 2, 3, 4, 5, 6]
```

#### get(string|int|null $index): mixed

[](#getstringintnull-index-mixed)

Get the underlying array data by index.

```
$u = underscore([1, 2, 3]);

$u->get();  // [1, 2, 3]
$u->get(1); // 2
$u->get(3); // 3
```

#### getData(): array

[](#getdata-array)

Get data.

```
// same as `get()` without args:
underscore([1, 2, 3])->getData(); // [1, 2, 3]
```

#### getIterator(): \\ArrayIterator

[](#getiterator-arrayiterator)

Gets the iterator for looping.

```
$it = underscore([1, 2, 3])->getIterator();

while ($it->valid()) {
    echo $it->current();
}
```

#### invert(): self

[](#invert-self)

Swap index and value of all the items. The values should be stringifiable.

```
$u = underscore(['a' => 1, 'b' => 2, 'c' => 3]);

$u->invert()->get(); // [1 => 'a', 2 => 'b', 3 => 'c']
```

#### jsonSerialize(): array

[](#jsonserialize-array)

Gets the data for json serialization.

```
$u = underscore(['a' => 1, 'b' => 2, 'c' => 3]);

json_encode($u); // {"a":1,"b":2,"c":3}
```

#### keys(): self

[](#keys-self)

Get all the keys.

```
$u = underscore(['a' => 1, 'b' => 2, 'c' => 3, 5]);

$u->keys()->get(); // ['a', 'b', 'c', 0]
```

#### mixin(string $name, \\Closure $fn): self

[](#mixinstring-name-closure-fn-self)

Adds a custom handler/method to instance. The handler is bound to this instance.

```
Ahc\Underscore\Underscore::mixin('square', function () {
    return $this->map(function ($v) { return $v * $v; });
});

underscore([1, 2, 3])->square()->get(); // [1, 4, 9]
```

#### now(): float

[](#now-float)

The current time in millisec.

```
underscore()->now(); // 1529996371081
```

#### omit(array|...string|...int $index): self

[](#omitarraystringint-index-self)

Omit the items having one of the blacklisted indexes.

```
$u = underscore(['a' => 3, 7, 'b' => 'B', 1 => ['c', 5]]);

$u->omit('a', 0)->get(); // ['b' => 'B', 1 => ['c', 5]]
```

#### pairs(): self

[](#pairs-self)

Pair all items to use an array of index and value.

```
$u = ['a' => 3, 7, 'b' => 'B'];

$u->pair(); // ['a' => ['a', 3], 0 => [0, 7], 'b' => ['b', 'B']
```

#### pick(array|...string|...int $index): self

[](#pickarraystringint-index-self)

Pick only the items having one of the whitelisted indexes.

```
$u = underscore(['a' => 3, 7, 'b' => 'B', 1 => ['c', 5]]);

$u->pick(0, 1)->get(); // [7, 1 => ['c', 5]]
```

#### tap(callable $fn): self

[](#tapcallable-fn-self)

Invokes callback fn with clone and returns original self.

```
$u = underscore([1, 2]);

$tap = $u->tap(function ($_) { return $_->values(); });

$tap === $u; // true
```

#### toArray(): array

[](#toarray-array)

Convert the data items to array.

```
$u = underscore([1, 3, 5, 7]);

$u->toArray(); // [1, 3, 5, 7]
```

#### valueOf(): string

[](#valueof-string)

Get string value (JSON representation) of this instance.

```
underscore(['a', 2, 'c' => 3])->valueOf(); // {0: "a", 1: 2, "c":3}
```

#### values(): self

[](#values-self)

Get all the values.

```
$u = underscore(['a' => 1, 'b' => 2, 'c' => 3, 5]);

$u->values()->get(); // [1, 2, 3, 5]
```

---

### UnderscoreAliases

[](#underscorealiases)

#### collect(callable $fn): self

[](#collectcallable-fn-self)

Alias of [map()](#map).

#### detect(callable $fn, bool $useValue): mixed|null

[](#detectcallable-fn-bool-usevalue-mixednull)

Alias of [find()](#find).

#### drop(int $n): array|mixed

[](#dropint-n-arraymixed)

Alias of [last()](#last).

#### foldl(callable $fn, mixed $memo): mixed

[](#foldlcallable-fn-mixed-memo-mixed)

Alias of [reduce()](#reduce).

#### foldr(callable $fn, mixed $memo): mixed

[](#foldrcallable-fn-mixed-memo-mixed)

Alias of [reduceRight()](#reduceRight).

#### head(int $n): array|mixed

[](#headint-n-arraymixed)

Alias of [first()](#first).

#### includes(): void

[](#includes-void)

Alias of [contains()](#contains).

#### inject(callable $fn, mixed $memo): mixed

[](#injectcallable-fn-mixed-memo-mixed)

Alias of [reduce()](#reduce).

#### select(callable|string|null $fn): self

[](#selectcallablestringnull-fn-self)

Alias of [filter()](#filter).

#### size(): int

[](#size-int)

Alias of [count()](#count).

#### tail(int $n): array|mixed

[](#tailint-n-arraymixed)

Alias of [last()](#last).

#### take(int $n): array|mixed

[](#takeint-n-arraymixed)

Alias of [first()](#first).

#### uniq(callable|string $fn): self

[](#uniqcallablestring-fn-self)

Alias of [unique()](#unique).

#### without(array|mixed $data): self

[](#withoutarraymixed-data-self)

Alias of [difference()](#difference).

---

### HigherOrderMessage

[](#higherordermessage)

A syntatic sugar to use elegant shorthand oneliner for complex logic often wrapped in closures. See example below:

```
// Higher Order Messaging
class HOM
{
    protected $n;
    public $square;

    public function __construct($n)
    {
        $this->n      = $n;
        $this->square = $n * $n;
    }

    public function even()
    {
        return $this->n % 2 === 0;
    }
}

$u = [new HOM(1), new HOM(2), new HOM(3), new HOM(4)];

// Filter `even()` items
$evens = $u->filter->even(); // 'even()' method of each items!

// Map each evens to their squares
$squares = $evens->map->square; // 'square' prop of each items!
// Gives an Underscore instance

// Get the data
$squares->get();
// [1 => 4, 3 => 16]
```

Without higher order messaging that would look like:

```
$evens = $u->filter(function ($it) {
    return $it->even();
});

$squares = $evens->map(function ($it) {
    return $it->square;
});
```

---

### \\ArrayAccess

[](#arrayaccess)

Underscore instances can be treated as array:

```
$u = underscore([1, 2, 'a' => 3]);

isset($u['a']); // true
isset($u['b']); // false

echo $u[1];     // 2

$u['b'] = 'B';
isset($u['b']); // true

unset($u[1]);
```

---

### Arrayizes

[](#arrayizes)

You can use this trait to arrayize all complex data.

```
use Ahc\Underscore\Arrayizes;

class Any
{
    use Arrayizes;

    public function name()
    {
        $this->asArray($data);
    }
}
```

---

#### License

[](#license)

> [MIT](./LICENSE) | © 2017-2018 | Jitendra Adhikari

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity30

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 96.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 ~595 days

Total

4

Last Release

1321d ago

Major Versions

v0.1.0 → v1.0.02022-10-02

PHP version history (2 changes)v0.0.1PHP &gt;=5.4.0

v1.0.0PHP &gt;=8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2908547?v=4)[Jitendra Adhikari](/maintainers/adhocore)[@adhocore](https://github.com/adhocore)

---

Top Contributors

[![adhocore](https://avatars.githubusercontent.com/u/2908547?v=4)](https://github.com/adhocore "adhocore (122 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (2 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (1 commits)")

---

Tags

adhocorearray-utilsarrayifyarrayizecollectioncollectionsfluentfluent-interfacehigher-order-messagelodash-phpphpphp-collectionphp-functionalphp-underscorethrottle-functionunderscorephpcollectionunderscore

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/adhocore-underscore/health.svg)

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

###  Alternatives

[mpetrovich/dash

A functional programming library for PHP. Inspired by Underscore, Lodash, and Ramda.

10428.9k1](/packages/mpetrovich-dash)[bdelespierre/underscore

Underscore.js port in PHP

6943.7k1](/packages/bdelespierre-underscore)[werxe/laravel-collection-macros

Custom Laravel Collection macros.

2625.8k](/packages/werxe-laravel-collection-macros)[iteks/laravel-enum

A comprehensive Laravel package providing enhanced enum functionalities, including attribute handling, select array conversions, and fluent facade interactions for robust enum management in Laravel applications.

2516.7k](/packages/iteks-laravel-enum)[jshannon63/jsoncollect

Supercharge your JSON using collections

154.9k1](/packages/jshannon63-jsoncollect)

PHPackages © 2026

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