This file documents project conventions, architecture, and findings from agent interactions. It is intended to help AI coding agents work effectively in this repository.
- Package:
voku/arrayy - Description: Array manipulation library for PHP
- License: MIT
- Maintainer: Lars Moelleken
- PHP requirement:
>=8.0.0 - Autoload namespace:
Arrayy\→src/ - Helper function namespace:
src/Create.php(defines globala()helper)
src/
Arrayy.php # Main class (~8000+ lines), all array methods live here
ArrayyStrict.php # Strict-typed subclass of Arrayy
ArrayyMeta.php # Meta/magic property helper (~67 lines)
ArrayyIterator.php # Custom iterator
ArrayyRewindableGenerator.php # Generator-backed iteration
ArrayyRewindableExtendedGenerator.php
Create.php # Global helper functions (a(), etc.)
StaticArrayy.php # Static façade using __callStatic
Collection/ # Collection base classes
Type/ # Typed collections (StringCollection, ArrayCollection, etc.)
TypeCheck/ # Type-checking utilities
Mapper/ # JSON mapper
tests/
ArrayyTest.php # Main test file (~6500+ lines), all tests in one class
build/
generate_docs.php # Regenerates README.md from src/Arrayy.php + build/docs/base.md
composer.json # Requires voku/php-readme-helper for doc generation
docs/base.md # Base template for README generation
examples/
JsonResponseDataExample.php
php vendor/bin/phpunit --no-coverage- Tests use PHPUnit (supports
~6.0 || ~7.0 || ~9.0) - All tests are in a single class
Arrayy\tests\ArrayyTestintests/ArrayyTest.php - Known pre-existing failures (unrelated to feature work): 2 errors (
array_sumon strings) + 1 failure (sigma case) - Run targeted tests with
--filter "testMethodName"to speed up iteration
The README is auto-generated — do not edit it manually.
# Install build dependencies first (only needed once):
cd build && composer install && cd ..
# Also install main project dependencies (needed by generate_docs.php):
composer install --no-dev
# Generate README:
php build/generate_docs.phpThis reads src/Arrayy.php docblocks and build/docs/base.md, then writes README.md.
- Rebuild the README with
php build/generate_docs.php - That script requires both:
vendor/autoload.phpbuild/vendor/autoload.php
- On this branch, rerunning the generator completed successfully and did not change
README.md AGENTS.mdis manually maintained and should be updated separately after README regeneration when task-specific context needs to be preserved
All public methods in src/Arrayy.php follow this pattern:
-
PHPDoc block with:
- Description
EXAMPLE: <code>...</code>block (used in README generation)@paramand@returntags@phpstan-param/@phpstan-returnfor generics (TKey,T)@psalm-mutation-freeif the method is immutable
-
Method signature — use
selfreturn type for immutable methods,$thisfor mutable -
Implementation — prefer
$this->getGenerator()for lazy iteration -
Test in
tests/ArrayyTest.php:- Add a
{method}Provider()data provider method - Add a
test{Method}()test method with@dataProvider - Place tests alphabetically relative to similar methods
- Add a
-
Rebuild README by running
php build/generate_docs.php
- Immutable methods return
staticand create a new instance viastatic::create() - Mutable methods return
$thisand modify$this->arraydirectly
- Use
$this->getGenerator()instead of$this->arrayto support lazy/generator-backed arrays - Call
$this->generatorToArray()first if you need direct array access
/**
* @template TKey of array-key
* @template T
*/
class Arrayy ...Use @phpstan-param T $value and @phpstan-return TKey|false etc. for PHPStan generics.
StaticArrayy uses __callStatic to delegate all calls to an Arrayy instance — no changes needed there when adding instance methods.
Problem: No method existed to find the key/index of an array element by a predicate callable. The existing methods were:
find(\Closure $closure)— returns the matching value, orfalsesearchIndex($value)— returns the key for an exact value matchindexOf($value)— alias forsearchIndex()
Solution: Added findKey(\Closure $closure) in src/Arrayy.php (after find()):
- Accepts
\Closurewith signature($value, $key): bool - Iterates via
$this->getGenerator()for generator compatibility - Returns the key of the first matching element, or
false
Usage examples:
// Find index of minimum value
$minIdx = a([3, 1, 4, 1, 5, 9])->findKey(fn($v) => $v === 1); // 1
// Find by key
a(['a' => 10, 'b' => 20])->findKey(fn($v, $k) => $k === 'b'); // 'b'
// Returns false when no match
a([1, 2, 3])->findKey(fn($v) => $v === 99); // falseTest coverage added:
findKeyProvider()— 11 data-driven cases covering empty arrays, booleans, integers, floats, strings, string keys, and no-matchtestFindKey()— value-based matching via data providertestFindKeyWithKeyParameter()— verifies$keyis correctly forwarded to the closure
Files excluded from Composer distribution (export-ignore):
/build,/examples,/tests- Config files:
.editorconfig,.scrutinizer.yml,.styleci.yml, etc. AGENTS.md(this file)
symfony/polyfill-mbstring~1.0phpdocumentor/reflection-docblock~6.0
phpunit/phpunit~6.0 || ~7.0 || ~9.0phpstan/phpstan^2.0
voku/php-readme-helper~0.6