{"id":15307868,"url":"https://github.com/samsonasik/arraylookup","last_synced_at":"2026-02-15T17:27:28.534Z","repository":{"id":65182505,"uuid":"586013992","full_name":"samsonasik/ArrayLookup","owner":"samsonasik","description":"🚀 A fast lookup library that help you verify and search array and Traversable data.","archived":false,"fork":false,"pushed_at":"2025-01-16T17:55:15.000Z","size":214,"stargazers_count":24,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-13T02:14:05.818Z","etag":null,"topics":["array","atleast","fast","filter","find","finder","iterable","lookup","only","php","search","traversable"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samsonasik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"samsonasik"}},"created_at":"2023-01-06T17:51:15.000Z","updated_at":"2025-03-03T18:37:41.000Z","dependencies_parsed_at":"2024-09-07T14:40:39.140Z","dependency_job_id":"79307ae5-74e1-4cc7-ad19-8f218a6de2f1","html_url":"https://github.com/samsonasik/ArrayLookup","commit_stats":{"total_commits":93,"total_committers":1,"mean_commits":93.0,"dds":0.0,"last_synced_commit":"6cfe695cae85feb315862a1e61812b29994109f9"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samsonasik%2FArrayLookup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samsonasik%2FArrayLookup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samsonasik%2FArrayLookup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samsonasik%2FArrayLookup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samsonasik","download_url":"https://codeload.github.com/samsonasik/ArrayLookup/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654476,"owners_count":21140309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["array","atleast","fast","filter","find","finder","iterable","lookup","only","php","search","traversable"],"created_at":"2024-10-01T08:12:32.132Z","updated_at":"2026-02-15T17:27:28.514Z","avatar_url":"https://github.com/samsonasik.png","language":"PHP","funding_links":["https://github.com/sponsors/samsonasik"],"categories":[],"sub_categories":[],"readme":"ArrayLookup\n===============\n\n[![Latest Version](https://img.shields.io/github/release/samsonasik/ArrayLookup.svg?style=flat-square)](https://github.com/samsonasik/ArrayLookup/releases)\n![ci build](https://github.com/samsonasik/ArrayLookup/workflows/ci%20build/badge.svg)\n[![Code Coverage](https://codecov.io/gh/samsonasik/ArrayLookup/branch/main/graph/badge.svg)](https://codecov.io/gh/samsonasik/ArrayLookup)\n[![PHPStan](https://img.shields.io/badge/style-level%20max-brightgreen.svg?style=flat-square\u0026label=phpstan)](https://github.com/phpstan/phpstan)\n[![Downloads](https://poser.pugx.org/samsonasik/array-lookup/downloads)](https://packagist.org/packages/samsonasik/array-lookup)\n\nIntroduction\n------------\n\nArrayLookup is a fast lookup library that help you verify and search `array` and `Traversable` data.\n\nFeatures\n--------\n\n- [x] Verify at least times: [`once()`](#1-atleastonce), [`twice()`](#2-atleasttwice), [`times()`](#3-atleasttimes)\n- [x] Verify at most times: [`once()`](#1-atmostonce), [`twice()`](#2-atmosttwice), [`times()`](#3-atmosttimes)\n- [x] Verify exact times: [`once()`](#1-onlyonce), [`twice()`](#2-onlytwice), [`times()`](#3-onlytimes)\n- [x] Verify in interval range: [`isInclusiveOf()`](#1-intervalisinclusiveof), [`isExclusiveOf()`](#2-intervalisexclusiveof)\n- [x] Search data: [`first()`](#1-finderfirst), [`last()`](#2-finderlast), [`rows()`](#3-finderrows), [`partition()`](#4-finderpartition)\n- [x] Collect data with [filter and transform](#f-collector)\n\nInstallation\n------------\n\n**Require this library uses [composer](https://getcomposer.org/).**\n\n```sh\ncomposer require samsonasik/array-lookup\n```\n\nUsage\n-----\n\n**A. AtLeast**\n---------------\n\n#### 1. `AtLeast::once()`\n\nIt verify that data has filtered found item at least once.\n\n```php\nuse ArrayLookup\\AtLeast;\n\n$data = [1, 2, 3];\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(AtLeast::once($data, $filter)) // true\n\n$data = [1, 2, 3];\n$filter = static fn($datum): bool =\u003e $datum === 4;\n\nvar_dump(AtLeast::once($data, $filter)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [1, 2, 3];\n$filter = static fn($datum, $key): bool =\u003e $datum === 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(AtLeast::once($data, $filter)) // true\n\n$data = [1, 2, 3];\n$filter = static fn($datum, $key): bool =\u003e $datum === 4 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(AtLeast::once($data, $filter)) // false\n```\n\n#### 2. `AtLeast::twice()`\n\nIt verify that data has filtered found items at least twice.\n\n```php\nuse ArrayLookup\\AtLeast;\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(AtLeast::twice($data, $filter)) // true\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(AtLeast::twice($data, $filter)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum, $key): bool =\u003e $datum == 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(AtLeast::twice($data, $filter)) // true\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum, $key): bool =\u003e $datum === 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(AtLeast::twice($data, $filter)) // false\n```\n\n#### 3. `AtLeast::times()`\n\nIt verify that data has filtered found items at least times passed in 3rd arg.\n\n```php\nuse ArrayLookup\\AtLeast;\n\n$data = [false, null, 0];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 3;\n\nvar_dump(AtLeast::times($data, $filter, $times)) // true\n\n$data = [1, null, 0];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 3;\n\nvar_dump(AtLeast::times($data, $filter, $times)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [false, null, 0];\n$filter = static fn($datum, $key): bool =\u003e ! $datum \u0026\u0026 $key \u003e= 0;\n$times = 3;\n\nvar_dump(AtLeast::times($data, $filter, $times)) // true\n\n$data = [1, null, 0];\n$filter = static fn($datum, $key): bool =\u003e ! $datum \u0026\u0026 $key \u003e= 0;\n$times = 3;\n\nvar_dump(AtLeast::times($data, $filter, $times)) // false\n```\n\n**B. AtMost**\n---------------\n\n#### 1. `AtMost::once()`\n\nIt verify that data has filtered found item at most once.\n\n```php\nuse ArrayLookup\\AtMost;\n\n$data = [1, 2, 3];\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(AtMost::once($data, $filter)) // true\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(AtMost::once($data, $filter)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = ['abc', 'def', 'some test'];\n$filter = static fn(string $datum, int $key): bool =\u003e $datum === 'def' \u0026\u0026 $key === 1;\n\nvar_dump(AtMost::once($data, $filter)) // true\n\n$data = ['abc', 'def', 'some test'];\n$filter = static fn(string $datum, int $key): bool =\u003e $key \u003e 0;\n\nvar_dump(AtMost::once($data, $filter)) // false\n```\n\n#### 2. `AtMost::twice()`\n\nIt verify that data has filtered found items at most twice.\n\n```php\nuse ArrayLookup\\AtMost;\n\n$data = [1, \"1\", 2];\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(AtMost::twice($data, $filter)) // true\n\n$data = [1, \"1\", 2, 1];\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(AtMost::twice($data, $filter)) // false\n```\n\n#### 3. `AtMost::times()`\n\nIt verify that data has filtered found items at most times passed in 3rd arg.\n\n```php\nuse ArrayLookup\\AtMost;\n\n$data = [false, null, 0];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 3;\n\nvar_dump(AtMost::times($data, $filter, $times)) // true\n\n$data = [false, null, 0, 0];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 3;\n\nvar_dump(AtMost::times($data, $filter, $times)) // false\n```\n\n**C. Only**\n---------------\n\n#### 1. `Only::once()`\n\nIt verify that data has filtered found item exactly found only once.\n\n```php\nuse ArrayLookup\\Only;\n\n$data = [1, 2, 3];\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(Only::once($data, $filter)) // true\n\n\n$data = [1, \"1\", 3]\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(Only::once($data, $filter)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [1, 2, 3];\n$filter = static fn($datum, $key): bool =\u003e $datum === 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(Only::once($data, $filter)) // true\n\n\n$data = [1, \"1\", 3]\n$filter = static fn($datum, $key): bool =\u003e $datum == 1  \u0026\u0026 $key \u003e= 0;\n\nvar_dump(Only::once($data, $filter)) // false\n```\n\n#### 2. `Only::twice()`\n\nIt verify that data has filtered found items exactly found only twice.\n\n```php\nuse ArrayLookup\\Only;\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum): bool =\u003e $datum == 1;\n\nvar_dump(Only::twice($data, $filter)) // true\n\n$data = [true, 1, new stdClass()];\n$filter = static fn($datum): bool =\u003e (bool) $datum;\n\nvar_dump(Only::twice($data, $filter)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [1, \"1\", 3];\n$filter = static fn($datum, $key): bool =\u003e $datum == 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(Only::twice($data, $filter)) // true\n\n$data = [true, 1, new stdClass()];\n$filter = static fn($datum, $key): bool =\u003e (bool) $datum \u0026\u0026 $key \u003e= 0;\n\nvar_dump(Only::twice($data, $filter)) // false\n```\n\n#### 3. `Only::times()`\n\nIt verify that data has filtered found items exactly found only same with times passed in 3rd arg.\n\n```php\nuse ArrayLookup\\Only;\n\n$data = [false, null, 1];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 2;\n\nvar_dump(Only::times($data, $filter, $times)) // true\n\n\n$data = [false, null, 0];\n$filter = static fn($datum): bool =\u003e ! $datum;\n$times = 2;\n\nvar_dump(Only::times($data, $filter, $times)) // false\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$data = [false, null, 1];\n$filter = static fn($datum, $key): bool =\u003e ! $datum \u0026\u0026 $key \u003e= 0;\n$times = 2;\n\nvar_dump(Only::times($data, $filter, $times)) // true\n\n\n$data = [false, null, 0];\n$filter = static fn($datum, $key): bool =\u003e ! $datum \u0026\u0026 $key \u003e= 0;\n$times = 2;\n\nvar_dump(Only::times($data, $filter, $times)) // false\n```\n\n**D. Interval**\n---------------\n\n#### 1. `Interval::isInclusiveOf()`\n\nIt verify that data has filtered found items within min and max (inclusive).\n\n```php\nuse ArrayLookup\\Interval;\n\n$orders = [\n    ['status' =\u003e 'paid'],\n    ['status' =\u003e 'paid'],\n    ['status' =\u003e 'pending'],\n    ['status' =\u003e 'paid'],\n];\n\n$filter = static fn(array $order): bool =\u003e $order['status'] === 'paid';\n\n// inclusive means min and max boundaries are allowed\nvar_dump(Interval::isInclusiveOf($orders, $filter, 3, 5)) // true\nvar_dump(Interval::isInclusiveOf($orders, $filter, 2, 5)) // true\n```\n\n#### 2. `Interval::isExclusiveOf()`\n\nIt verify that data has filtered found items between min and max (exclusive).\n\n```php\nuse ArrayLookup\\Interval;\n\n$orders = [\n    ['status' =\u003e 'paid'],\n    ['status' =\u003e 'paid'],\n    ['status' =\u003e 'pending'],\n    ['status' =\u003e 'paid'],\n];\n\n$filter = static fn(array $order): bool =\u003e $order['status'] === 'paid';\n\n// exclusive means strictly between min and max\nvar_dump(Interval::isExclusiveOf($orders, $filter, 3, 5)) // false\nvar_dump(Interval::isExclusiveOf($orders, $filter, 2, 5)) // true\n```\n\n**E. Finder**\n---------------\n\n#### 1. `Finder::first()`\n\nIt search first data filtered found.\n\n```php\nuse ArrayLookup\\Finder;\n\n$data = [1, 2, 3];\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(Finder::first($data, $filter)) // 1\n\n$filter = static fn($datum): bool =\u003e $datum == 1000;\nvar_dump(Finder::first($data, $filter)) // null\n\n// RETURN the Array key, pass true to 3rd arg\n\n$filter = static fn($datum): bool =\u003e $datum === 1;\n\nvar_dump(Finder::first($data, $filter, true)) // 0\n\n$filter = static fn($datum): bool =\u003e $datum == 1000;\nvar_dump(Finder::first($data, $filter, true)) // null\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\n$filter = static fn($datum, $key): bool =\u003e $datum === 1 \u0026\u0026 $key \u003e= 0;\n\nvar_dump(Finder::first($data, $filter)) // 1\n\n$filter = static fn($datum, $key): bool =\u003e $datum == 1000 \u0026\u0026 $key \u003e= 0;\nvar_dump(Finder::first($data, $filter)) // null\n```\n\n#### 2. `Finder::last()`\n\nIt search last data filtered found.\n\n```php\nuse ArrayLookup\\Finder;\n\n$data = [6, 7, 8, 9];\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003e 5\n)); // 9\n\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003c 5\n)); // null\n\n// RETURN the Array key, pass true to 3rd arg\n\n// ... with PRESERVE original key\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003e 5,\n    true\n)); // 3\n\n// ... with RESORT key, first key is last record\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003e 5,\n    true,\n    false\n)); // 0\n\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003c 5,\n    true\n)); // null\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\n\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum, $key): bool =\u003e $datum \u003e 5 \u0026\u0026 $key \u003e= 0\n)); // 9\n\nvar_dump(Finder::last(\n    $data,\n    static fn ($datum, $key): bool =\u003e $datum \u003c 5 \u0026\u0026 $key \u003e= 0\n)); // null\n```\n\n#### 3. `Finder::rows()`\n\nIt get rows data filtered found.\n\n```php\nuse ArrayLookup\\Finder;\n\n$data = [6, 7, 8, 9];\nvar_dump(Finder::rows(\n    $data,\n    static fn($datum): bool =\u003e $datum \u003e 6\n)); // [7, 8, 9]\n\nvar_dump(Finder::rows(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003c 5\n)); // []\n\n// ... with PRESERVE original key\nvar_dump(Finder::rows(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003e 6,\n    true\n)); // [1 =\u003e 7, 2 =\u003e 8, 3 =\u003e 9]\n\nvar_dump(Finder::rows(\n    $data,\n    static fn ($datum): bool =\u003e $datum \u003c 5,\n    true\n)); // []\n\n// WITH key array included, pass $key variable as 2nd arg on  filter to be used in filter\nvar_dump(Finder::rows(\n    $data,\n    static fn($datum, $key): bool =\u003e $datum \u003e 6 \u0026\u0026 $key \u003e 1\n)); // [8, 9]\n\n\n// WITH gather only limited found data\n$data = [1, 2];\n$filter = static fn($datum): bool =\u003e $datum \u003e= 0;\n$limit = 1;\n\nvar_dump(\n    Finder::rows($data, $filter, limit: $limit)\n); // [1]\n```\n\n#### 4. `Finder::partition()`\n\nIt splits data into two arrays: matching and non-matching items based on a filter.\n\n```php\nuse ArrayLookup\\Finder;\n\n// Basic partition - split numbers into greater than 5 and not\n$data = [1, 6, 3, 8, 4, 9];\n$filter = static fn($datum): bool =\u003e $datum \u003e 5;\n\n[$matching, $notMatching] = Finder::partition($data, $filter);\n\nvar_dump($matching);    // [6, 8, 9]\nvar_dump($notMatching); // [1, 3, 4]\n\n// Partition with preserved keys\n[$matching, $notMatching] = Finder::partition($data, $filter, preserveKey: true);\n\nvar_dump($matching);    // [1 =\u003e 6, 3 =\u003e 8, 5 =\u003e 9]\nvar_dump($notMatching); // [0 =\u003e 1, 2 =\u003e 3, 4 =\u003e 4]\n\n// Using the array key inside the filter\n$data = [10, 20, 30, 40];\n$keyFilter = static fn($datum, $key): bool =\u003e $key % 2 === 0;\n\n[$even, $odd] = Finder::partition($data, $keyFilter, preserveKey: true);\n\nvar_dump($even); // [0 =\u003e 10, 2 =\u003e 30]\nvar_dump($odd);  // [1 =\u003e 20, 3 =\u003e 40]\n```\n\n**F. Collector**\n---------------\n\nIt collect filtered data, with new transformed each data found:\n\n**Before**\n\n```php\n$newArray = [];\n\nforeach ($data as $datum) {\n    if (is_string($datum)) {\n        $newArray[] = trim($datum);\n    }\n}\n```\n\n**After**\n\n```php\nuse ArrayLookup\\Collector;\n\n$when = fn ($datum): bool =\u003e is_string($datum);\n$limit = 2;\n$transform = fn ($datum): string =\u003e trim($datum);\n\n$newArray = Collector::setUp($data)\n       -\u003ewhen($when) // optional, can just transform without filtering\n       -\u003ewithLimit(2) // optional to only collect some data provided by limit config\n       -\u003ewithTransform($transform)\n       -\u003egetResults();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamsonasik%2Farraylookup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamsonasik%2Farraylookup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamsonasik%2Farraylookup/lists"}