PHPackages                             samsonasik/array-lookup - 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. [File &amp; Storage](/categories/file-storage)
4. /
5. samsonasik/array-lookup

ActiveLibrary[File &amp; Storage](/categories/file-storage)

samsonasik/array-lookup
=======================

A fast lookup library that help you verify and search array and Traversable data

2.5.1(2mo ago)2863.0k↑21.4%32MITPHPPHP ^8.2CI passing

Since Jan 6Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/samsonasik/ArrayLookup)[ Packagist](https://packagist.org/packages/samsonasik/array-lookup)[ Docs](https://github.com/samsonasik/ArrayLookup)[ GitHub Sponsors](https://github.com/samsonasik)[ RSS](/packages/samsonasik-array-lookup/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (12)Versions (40)Used By (2)

ArrayLookup
===========

[](#arraylookup)

[![Latest Version](https://camo.githubusercontent.com/f820485fee4e11498c12b17e8ae9e9cf5b428605c08204cc2b7bcfc1269d539a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f73616d736f6e6173696b2f41727261794c6f6f6b75702e7376673f7374796c653d666c61742d737175617265)](https://github.com/samsonasik/ArrayLookup/releases)[![ci build](https://github.com/samsonasik/ArrayLookup/workflows/ci%20build/badge.svg)](https://github.com/samsonasik/ArrayLookup/workflows/ci%20build/badge.svg)[![Code Coverage](https://camo.githubusercontent.com/81b89aad3dd3ff8a0fab267cf62480496207c46b806dde817864b3e98deefcd7/68747470733a2f2f636f6465636f762e696f2f67682f73616d736f6e6173696b2f41727261794c6f6f6b75702f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/samsonasik/ArrayLookup)[![PHPStan](https://camo.githubusercontent.com/fdcdf50c27377a0f41a7196eeaae8539c4684bfc8a1f9843fdac60fdbc53deab/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374796c652d6c6576656c2532306d61782d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265266c6162656c3d7068707374616e)](https://github.com/phpstan/phpstan)[![Downloads](https://camo.githubusercontent.com/60b0be9c8ea5e51fca9602a6b8f5a0cc39da3525bc9f06516b0d6b6a485ba6f2/68747470733a2f2f706f7365722e707567782e6f72672f73616d736f6e6173696b2f61727261792d6c6f6f6b75702f646f776e6c6f616473)](https://packagist.org/packages/samsonasik/array-lookup)

Introduction
------------

[](#introduction)

ArrayLookup is a fast lookup library that helps you verify and search `array` and `Traversable` data.

Features
--------

[](#features)

- Verify at least times: [`once()`](#1-atleastonce), [`twice()`](#2-atleasttwice), [`times()`](#3-atleasttimes)
- Verify at most times: [`once()`](#1-atmostonce), [`twice()`](#2-atmosttwice), [`times()`](#3-atmosttimes)
- Verify exact times: [`once()`](#1-onlyonce), [`twice()`](#2-onlytwice), [`times()`](#3-onlytimes)
- Verify in interval range: [`isInclusiveOf()`](#1-intervalisinclusiveof), [`isExclusiveOf()`](#2-intervalisexclusiveof)
- Verify all or none match: [`match()`](#1-allmatch), [`none()`](#2-allnone)
- Search data: [`first()`](#1-finderfirst), [`last()`](#2-finderlast), [`rows()`](#3-finderrows), [`partition()`](#4-finderpartition)
- Collect data with [filter and transform](#g-collector)

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

[](#installation)

**Require this library uses [composer](https://getcomposer.org/).**

```
composer require samsonasik/array-lookup
```

Usage
-----

[](#usage)

**A. AtLeast**
--------------

[](#a-atleast)

#### 1. `AtLeast::once()`

[](#1-atleastonce)

It verify that data has filtered found item at least once.

```
use ArrayLookup\AtLeast;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 1;

var_dump(AtLeast::once($data, $filter)) // true

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 4;

var_dump(AtLeast::once($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [1, 2, 3];
$filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0;

var_dump(AtLeast::once($data, $filter)) // true

$data = [1, 2, 3];
$filter = static fn($datum, $key): bool => $datum === 4 && $key >= 0;

var_dump(AtLeast::once($data, $filter)) // false
```

#### 2. `AtLeast::twice()`

[](#2-atleasttwice)

It verify that data has filtered found items at least twice.

```
use ArrayLookup\AtLeast;

$data = [1, "1", 3];
$filter = static fn($datum): bool => $datum == 1;

var_dump(AtLeast::twice($data, $filter)) // true

$data = [1, "1", 3];
$filter = static fn($datum): bool => $datum === 1;

var_dump(AtLeast::twice($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [1, "1", 3];
$filter = static fn($datum, $key): bool => $datum == 1 && $key >= 0;

var_dump(AtLeast::twice($data, $filter)) // true

$data = [1, "1", 3];
$filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0;

var_dump(AtLeast::twice($data, $filter)) // false
```

#### 3. `AtLeast::times()`

[](#3-atleasttimes)

It verify that data has filtered found items at least times passed in 3rd arg.

```
use ArrayLookup\AtLeast;

$data = [false, null, 0];
$filter = static fn($datum): bool => ! $datum;
$times = 3;

var_dump(AtLeast::times($data, $filter, $times)) // true

$data = [1, null, 0];
$filter = static fn($datum): bool => ! $datum;
$times = 3;

var_dump(AtLeast::times($data, $filter, $times)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [false, null, 0];
$filter = static fn($datum, $key): bool => ! $datum && $key >= 0;
$times = 3;

var_dump(AtLeast::times($data, $filter, $times)) // true

$data = [1, null, 0];
$filter = static fn($datum, $key): bool => ! $datum && $key >= 0;
$times = 3;

var_dump(AtLeast::times($data, $filter, $times)) // false
```

**B. AtMost**
-------------

[](#b-atmost)

#### 1. `AtMost::once()`

[](#1-atmostonce)

It verify that data has filtered found item at most once.

```
use ArrayLookup\AtMost;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 1;

var_dump(AtMost::once($data, $filter)) // true

$data = [1, "1", 3];
$filter = static fn($datum): bool => $datum == 1;

var_dump(AtMost::once($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = ['abc', 'def', 'some test'];
$filter = static fn(string $datum, int $key): bool => $datum === 'def' && $key === 1;

var_dump(AtMost::once($data, $filter)) // true

$data = ['abc', 'def', 'some test'];
$filter = static fn(string $datum, int $key): bool => $key > 0;

var_dump(AtMost::once($data, $filter)) // false
```

#### 2. `AtMost::twice()`

[](#2-atmosttwice)

It verify that data has filtered found items at most twice.

```
use ArrayLookup\AtMost;

$data = [1, "1", 2];
$filter = static fn($datum): bool => $datum == 1;

var_dump(AtMost::twice($data, $filter)) // true

$data = [1, "1", 2, 1];
$filter = static fn($datum): bool => $datum == 1;

var_dump(AtMost::twice($data, $filter)) // false
```

#### 3. `AtMost::times()`

[](#3-atmosttimes)

It verify that data has filtered found items at most times passed in 3rd arg.

```
use ArrayLookup\AtMost;

$data = [false, null, 0];
$filter = static fn($datum): bool => ! $datum;
$times = 3;

var_dump(AtMost::times($data, $filter, $times)) // true

$data = [false, null, 0, 0];
$filter = static fn($datum): bool => ! $datum;
$times = 3;

var_dump(AtMost::times($data, $filter, $times)) // false
```

**C. Only**
-----------

[](#c-only)

#### 1. `Only::once()`

[](#1-onlyonce)

It verify that data has filtered found item exactly found only once.

```
use ArrayLookup\Only;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 1;

var_dump(Only::once($data, $filter)) // true

$data = [1, "1", 3]
$filter = static fn($datum): bool => $datum == 1;

var_dump(Only::once($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [1, 2, 3];
$filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0;

var_dump(Only::once($data, $filter)) // true

$data = [1, "1", 3]
$filter = static fn($datum, $key): bool => $datum == 1  && $key >= 0;

var_dump(Only::once($data, $filter)) // false
```

#### 2. `Only::twice()`

[](#2-onlytwice)

It verify that data has filtered found items exactly found only twice.

```
use ArrayLookup\Only;

$data = [1, "1", 3];
$filter = static fn($datum): bool => $datum == 1;

var_dump(Only::twice($data, $filter)) // true

$data = [true, 1, new stdClass()];
$filter = static fn($datum): bool => (bool) $datum;

var_dump(Only::twice($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [1, "1", 3];
$filter = static fn($datum, $key): bool => $datum == 1 && $key >= 0;

var_dump(Only::twice($data, $filter)) // true

$data = [true, 1, new stdClass()];
$filter = static fn($datum, $key): bool => (bool) $datum && $key >= 0;

var_dump(Only::twice($data, $filter)) // false
```

#### 3. `Only::times()`

[](#3-onlytimes)

It verify that data has filtered found items exactly found only same with times passed in 3rd arg.

```
use ArrayLookup\Only;

$data = [false, null, 1];
$filter = static fn($datum): bool => ! $datum;
$times = 2;

var_dump(Only::times($data, $filter, $times)) // true

$data = [false, null, 0];
$filter = static fn($datum): bool => ! $datum;
$times = 2;

var_dump(Only::times($data, $filter, $times)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = [false, null, 1];
$filter = static fn($datum, $key): bool => ! $datum && $key >= 0;
$times = 2;

var_dump(Only::times($data, $filter, $times)) // true

$data = [false, null, 0];
$filter = static fn($datum, $key): bool => ! $datum && $key >= 0;
$times = 2;

var_dump(Only::times($data, $filter, $times)) // false
```

**D. Interval**
---------------

[](#d-interval)

#### 1. `Interval::isInclusiveOf()`

[](#1-intervalisinclusiveof)

It verify that data has filtered found items within min and max (inclusive).

```
use ArrayLookup\Interval;

$orders = [
    ['status' => 'paid'],
    ['status' => 'paid'],
    ['status' => 'pending'],
    ['status' => 'paid'],
];

$filter = static fn(array $order): bool => $order['status'] === 'paid';

// inclusive means min and max boundaries are allowed
var_dump(Interval::isInclusiveOf($orders, $filter, 3, 5)) // true
var_dump(Interval::isInclusiveOf($orders, $filter, 2, 5)) // true
```

#### 2. `Interval::isExclusiveOf()`

[](#2-intervalisexclusiveof)

It verify that data has filtered found items between min and max (exclusive).

```
use ArrayLookup\Interval;

$orders = [
    ['status' => 'paid'],
    ['status' => 'paid'],
    ['status' => 'pending'],
    ['status' => 'paid'],
];

$filter = static fn(array $order): bool => $order['status'] === 'paid';

// exclusive means strictly between min and max
var_dump(Interval::isExclusiveOf($orders, $filter, 3, 5)) // false
var_dump(Interval::isExclusiveOf($orders, $filter, 2, 5)) // true
```

**E. All**
----------

[](#e-all)

#### 1. `All::match()`

[](#1-allmatch)

It verify that all items match the filter and data is non-empty.

```
use ArrayLookup\All;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum > 0;

var_dump(All::match($data, $filter)) // true

$data = [1, 0, 3];
$filter = static fn($datum): bool => $datum > 0;

var_dump(All::match($data, $filter)) // false

$data = [];
$filter = static fn($datum): bool => $datum !== null;

var_dump(All::match($data, $filter)) // false

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = ['abc', 'def'];
$filter = static fn($datum, $key): bool => $datum !== '' && $key >= 0;

var_dump(All::match($data, $filter)) // true
```

#### 2. `All::none()`

[](#2-allnone)

It verify that no items match the filter (empty data returns true).

```
use ArrayLookup\All;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 4;

var_dump(All::none($data, $filter)) // true

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 2;

var_dump(All::none($data, $filter)) // false

$data = [];
$filter = static fn($datum): bool => $datum !== null;

var_dump(All::none($data, $filter)) // true

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$data = ['abc', 'def'];
$filter = static fn($datum, $key): bool => $key === 0 && $datum === 'abc';

var_dump(All::none($data, $filter)) // false
```

**F. Finder**
-------------

[](#f-finder)

#### 1. `Finder::first()`

[](#1-finderfirst)

It search first data filtered found.

```
use ArrayLookup\Finder;

$data = [1, 2, 3];
$filter = static fn($datum): bool => $datum === 1;

var_dump(Finder::first($data, $filter)) // 1

$filter = static fn($datum): bool => $datum == 1000;
var_dump(Finder::first($data, $filter)) // null

// RETURN the Array key, pass true to 3rd arg

$filter = static fn($datum): bool => $datum === 1;

var_dump(Finder::first($data, $filter, true)) // 0

$filter = static fn($datum): bool => $datum == 1000;
var_dump(Finder::first($data, $filter, true)) // null

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

$filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0;

var_dump(Finder::first($data, $filter)) // 1

$filter = static fn($datum, $key): bool => $datum == 1000 && $key >= 0;
var_dump(Finder::first($data, $filter)) // null
```

#### 2. `Finder::last()`

[](#2-finderlast)

It search last data filtered found.

```
use ArrayLookup\Finder;

$data = [6, 7, 8, 9];
var_dump(Finder::last(
    $data,
    static fn ($datum): bool => $datum > 5
)); // 9

var_dump(Finder::last(
    $data,
    static fn ($datum): bool => $datum < 5
)); // null

// RETURN the Array key, pass true to 3rd arg

// ... with PRESERVE original key
var_dump(Finder::last(
    $data,
    static fn ($datum): bool => $datum > 5,
    true
)); // 3

// ... with RESORT key, first key is last record
var_dump(Finder::last(
    $data,
    static fn ($datum): bool => $datum > 5,
    true,
    false
)); // 0

var_dump(Finder::last(
    $data,
    static fn ($datum): bool => $datum < 5,
    true
)); // null

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter

var_dump(Finder::last(
    $data,
    static fn ($datum, $key): bool => $datum > 5 && $key >= 0
)); // 9

var_dump(Finder::last(
    $data,
    static fn ($datum, $key): bool => $datum < 5 && $key >= 0
)); // null
```

#### 3. `Finder::rows()`

[](#3-finderrows)

It get rows data filtered found.

```
use ArrayLookup\Finder;

$data = [6, 7, 8, 9];
var_dump(Finder::rows(
    $data,
    static fn($datum): bool => $datum > 6
)); // [7, 8, 9]

var_dump(Finder::rows(
    $data,
    static fn ($datum): bool => $datum < 5
)); // []

// ... with PRESERVE original key
var_dump(Finder::rows(
    $data,
    static fn ($datum): bool => $datum > 6,
    true
)); // [1 => 7, 2 => 8, 3 => 9]

var_dump(Finder::rows(
    $data,
    static fn ($datum): bool => $datum < 5,
    true
)); // []

// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter
var_dump(Finder::rows(
    $data,
    static fn($datum, $key): bool => $datum > 6 && $key > 1
)); // [8, 9]

// WITH gather only limited found data
$data = [1, 2];
$filter = static fn($datum): bool => $datum >= 0;
$limit = 1;

var_dump(
    Finder::rows($data, $filter, limit: $limit)
); // [1]
```

#### 4. `Finder::partition()`

[](#4-finderpartition)

It splits data into two arrays: matching and non-matching items based on a filter.

```
use ArrayLookup\Finder;

// Basic partition - split numbers into greater than 5 and not
$data = [1, 6, 3, 8, 4, 9];
$filter = static fn($datum): bool => $datum > 5;

[$matching, $notMatching] = Finder::partition($data, $filter);

var_dump($matching);    // [6, 8, 9]
var_dump($notMatching); // [1, 3, 4]

// Partition with preserved keys
[$matching, $notMatching] = Finder::partition($data, $filter, preserveKey: true);

var_dump($matching);    // [1 => 6, 3 => 8, 5 => 9]
var_dump($notMatching); // [0 => 1, 2 => 3, 4 => 4]

// Using the array key inside the filter
$data = [10, 20, 30, 40];
$keyFilter = static fn($datum, $key): bool => $key % 2 === 0;

[$even, $odd] = Finder::partition($data, $keyFilter, preserveKey: true);

var_dump($even); // [0 => 10, 2 => 30]
var_dump($odd);  // [1 => 20, 3 => 40]
```

**G. Collector**
----------------

[](#g-collector)

It collect filtered data, with new transformed each data found:

**Before**

```
$newArray = [];

foreach ($data as $datum) {
    if (is_string($datum)) {
        $newArray[] = trim($datum);
    }
}
```

**After**

```
use ArrayLookup\Collector;

$when = fn ($datum): bool => is_string($datum);
$limit = 2;
$transform = fn ($datum): string => trim($datum);

$newArray = Collector::setUp($data)
       ->when($when) // optional, can just transform without filtering
       ->withLimit(2) // optional to only collect some data provided by limit config
       ->withTransform($transform)
       ->getResults();
```

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance85

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 99.1% 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 ~30 days

Recently: every ~3 days

Total

39

Last Release

81d ago

Major Versions

0.9.0 → 1.0.02023-01-09

1.x-dev → 2.0.02024-12-28

PHP version history (2 changes)0.0.1PHP ^8.1

2.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/19076b7688ca1c8ee79ab3ac6fa6acdd7b96012973aba3b1a06cbb3154d7f3e5?d=identicon)[samsonasik](/maintainers/samsonasik)

---

Top Contributors

[![samsonasik](https://avatars.githubusercontent.com/u/459648?v=4)](https://github.com/samsonasik "samsonasik (231 commits)")[![nynka](https://avatars.githubusercontent.com/u/7600194?v=4)](https://github.com/nynka "nynka (2 commits)")

---

Tags

arrayatleastfastfilterfindfinderiterablelookuponlyphpsearchtraversablesearcharrayfilterfinderfastsplcollectorlookupiterabletraversable

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Type Coverage Yes

### Embed Badge

![Health badge](/badges/samsonasik-array-lookup/health.svg)

```
[![Health](https://phpackages.com/badges/samsonasik-array-lookup/health.svg)](https://phpackages.com/packages/samsonasik-array-lookup)
```

###  Alternatives

[yosymfony/resource-watcher

A simple resource watcher using Symfony Finder

698.2M22](/packages/yosymfony-resource-watcher)[ergebnis/classy

Provides collectors for classy constructs (classes, enums, interfaces, and traits).

382.8M20](/packages/ergebnis-classy)[arthurhoaro/favicon

PHP Library used to discover favicon from given URL

36737.4k](/packages/arthurhoaro-favicon)[edsdk/flmngr-server-php

Flmngr file manager PHP backend

20279.5k3](/packages/edsdk-flmngr-server-php)[mpclarkson/icon-scraper

PHP Library to get the apple-touch-icons and favicon from a website.

2129.2k](/packages/mpclarkson-icon-scraper)

PHPackages © 2026

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