# Illuminate Collections Illuminate Collections is a powerful, fluent wrapper for working with arrays of data in PHP. It provides an expressive, chainable API for common operations like filtering, mapping, reducing, sorting, and transforming data collections. This package is a standalone component extracted from the Laravel framework, allowing developers to use Laravel's collection functionality in any PHP project. The library offers two main collection types: `Collection` for in-memory array manipulation, and `LazyCollection` for memory-efficient processing of large datasets using PHP generators. Both classes implement the `Enumerable` interface, providing a consistent API across collection types. The `Arr` helper class offers static methods for common array operations with support for "dot" notation for nested array access. ## Creating Collections The `collect()` helper function and `Collection::make()` static method create new collection instances from arrays or iterables. ```php use Illuminate\Support\Collection; // Using the helper function $collection = collect([1, 2, 3, 4, 5]); // Using static make method $collection = Collection::make(['name' => 'John', 'age' => 30]); // Create from JSON $collection = Collection::fromJson('{"name": "Jane", "city": "NYC"}'); // Create a range $numbers = Collection::range(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // Create using times $collection = Collection::times(5, fn($number) => $number * 2); // Result: [2, 4, 6, 8, 10] ``` ## Filtering Collections The `filter()`, `where()`, `reject()`, and related methods allow filtering items based on conditions or callbacks. ```php $collection = collect([ ['name' => 'Alice', 'age' => 25, 'active' => true], ['name' => 'Bob', 'age' => 30, 'active' => false], ['name' => 'Charlie', 'age' => 35, 'active' => true], ]); // Filter with callback $adults = $collection->filter(fn($person) => $person['age'] >= 30); // Result: Bob and Charlie // Where clause filtering $activeUsers = $collection->where('active', true); // Result: Alice and Charlie // Where with operators $olderUsers = $collection->where('age', '>=', 30); // Result: Bob and Charlie // WhereIn filtering $specific = $collection->whereIn('name', ['Alice', 'Charlie']); // WhereBetween $middleAged = $collection->whereBetween('age', [26, 34]); // Result: Bob // Reject (inverse of filter) $inactive = $collection->reject(fn($person) => $person['active']); // Result: Bob // WhereNull and WhereNotNull $collection = collect([ ['name' => 'John', 'email' => 'john@example.com'], ['name' => 'Jane', 'email' => null], ]); $withEmail = $collection->whereNotNull('email'); ``` ## Mapping and Transforming The `map()`, `mapWithKeys()`, `flatMap()`, `transform()`, and `pluck()` methods transform collection items. ```php $collection = collect([ ['id' => 1, 'name' => 'iPhone', 'price' => 999], ['id' => 2, 'name' => 'Galaxy', 'price' => 899], ['id' => 3, 'name' => 'Pixel', 'price' => 799], ]); // Map to transform each item $names = $collection->map(fn($product) => $product['name']); // Result: ['iPhone', 'Galaxy', 'Pixel'] // Map with keys to create associative array $priceList = $collection->mapWithKeys(fn($product) => [ $product['name'] => $product['price'] ]); // Result: ['iPhone' => 999, 'Galaxy' => 899, 'Pixel' => 799] // Pluck specific values $prices = $collection->pluck('price'); // Result: [999, 899, 799] // Pluck with custom keys $phonePrices = $collection->pluck('price', 'name'); // Result: ['iPhone' => 999, 'Galaxy' => 899, 'Pixel' => 799] // FlatMap for nested transformations $collection = collect([ ['tags' => ['php', 'laravel']], ['tags' => ['javascript', 'vue']], ]); $allTags = $collection->flatMap(fn($item) => $item['tags']); // Result: ['php', 'laravel', 'javascript', 'vue'] // Transform modifies the collection in place $collection = collect([1, 2, 3]); $collection->transform(fn($item) => $item * 2); // $collection is now [2, 4, 6] ``` ## Reducing and Aggregating The `reduce()`, `sum()`, `avg()`, `min()`, `max()`, `count()`, and statistical methods aggregate collection data. ```php $numbers = collect([1, 2, 3, 4, 5]); // Sum all values $total = $numbers->sum(); // 15 // Average $average = $numbers->avg(); // 3 // Min and Max $min = $numbers->min(); // 1 $max = $numbers->max(); // 5 // Reduce to custom value $product = $numbers->reduce(fn($carry, $item) => $carry * $item, 1); // Result: 120 (1*2*3*4*5) // With object collections $orders = collect([ ['product' => 'Laptop', 'price' => 1200, 'qty' => 2], ['product' => 'Mouse', 'price' => 50, 'qty' => 5], ['product' => 'Keyboard', 'price' => 100, 'qty' => 3], ]); $totalRevenue = $orders->sum(fn($order) => $order['price'] * $order['qty']); // Result: 2950 $avgPrice = $orders->avg('price'); // 450 // Median and Mode $scores = collect([85, 90, 78, 92, 88, 90, 85]); $median = $scores->median(); // 88 $mode = $scores->mode(); // [85, 90] // Percentage calculation $users = collect([ ['name' => 'John', 'active' => true], ['name' => 'Jane', 'active' => false], ['name' => 'Bob', 'active' => true], ]); $activePercentage = $users->percentage(fn($user) => $user['active']); // Result: 66.67 ``` ## Sorting The `sort()`, `sortBy()`, `sortByDesc()`, `sortKeys()` methods order collection items. ```php $collection = collect([ ['name' => 'Desk', 'price' => 200, 'category' => 'Office'], ['name' => 'Chair', 'price' => 100, 'category' => 'Office'], ['name' => 'Lamp', 'price' => 50, 'category' => 'Lighting'], ]); // Sort by key $byPrice = $collection->sortBy('price'); // Result: Lamp, Chair, Desk // Sort descending $byPriceDesc = $collection->sortByDesc('price'); // Result: Desk, Chair, Lamp // Sort by multiple keys $sorted = $collection->sortBy([ ['category', 'asc'], ['price', 'desc'], ]); // Result: Lamp (Lighting), Desk (Office, 200), Chair (Office, 100) // Sort with custom callback $sorted = $collection->sort(fn($a, $b) => strlen($a['name']) <=> strlen($b['name'])); // Sort keys $data = collect(['z' => 1, 'a' => 2, 'm' => 3]); $sorted = $data->sortKeys(); // Result: ['a' => 2, 'm' => 3, 'z' => 1] // Simple array sorting $numbers = collect([3, 1, 4, 1, 5, 9, 2, 6]); $sorted = $numbers->sort()->values(); // Result: [1, 1, 2, 3, 4, 5, 6, 9] ``` ## Grouping and Chunking The `groupBy()`, `keyBy()`, `chunk()`, `split()`, and partitioning methods organize collections into groups. ```php $collection = collect([ ['account_id' => 1, 'product' => 'Desk', 'price' => 200], ['account_id' => 1, 'product' => 'Chair', 'price' => 100], ['account_id' => 2, 'product' => 'Lamp', 'price' => 50], ['account_id' => 2, 'product' => 'Table', 'price' => 300], ]); // Group by key $grouped = $collection->groupBy('account_id'); // Result: [1 => [Desk, Chair], 2 => [Lamp, Table]] // Key by a field $keyed = $collection->keyBy('product'); // Result: ['Desk' => [...], 'Chair' => [...], ...] // Chunk into smaller collections $chunks = collect([1, 2, 3, 4, 5, 6, 7])->chunk(3); // Result: [[1, 2, 3], [4, 5, 6], [7]] // Split into n groups $groups = collect([1, 2, 3, 4, 5])->split(2); // Result: [[1, 2, 3], [4, 5]] // Partition by condition [$active, $inactive] = collect([ ['name' => 'John', 'active' => true], ['name' => 'Jane', 'active' => false], ['name' => 'Bob', 'active' => true], ])->partition(fn($user) => $user['active']); // $active: John, Bob; $inactive: Jane // ChunkWhile for conditional grouping $collection = collect('AAAAABBBCCD')->chunkWhile(fn($value, $key, $chunk) => $value === $chunk->last() ); // Result: [['A','A','A','A','A'], ['B','B','B'], ['C','C'], ['D']] ``` ## Slicing and Taking The `take()`, `skip()`, `slice()`, `first()`, `last()`, and related methods extract portions of collections. ```php $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // Take first n items $first3 = $collection->take(3); // [1, 2, 3] // Take last n items $last3 = $collection->take(-3); // [8, 9, 10] // Skip first n items $afterSkip = $collection->skip(3); // [4, 5, 6, 7, 8, 9, 10] // Slice with offset and length $slice = $collection->slice(2, 3); // [3, 4, 5] // First and last items $first = $collection->first(); // 1 $last = $collection->last(); // 10 // First matching condition $firstEven = $collection->first(fn($n) => $n % 2 === 0); // 2 // TakeWhile - take while condition is true $result = $collection->takeWhile(fn($n) => $n < 5); // Result: [1, 2, 3, 4] // SkipUntil - skip until condition is met $result = $collection->skipUntil(fn($n) => $n > 5); // Result: [6, 7, 8, 9, 10] // Pagination $page2 = $collection->forPage(2, 3); // Items 4, 5, 6 (page 2, 3 per page) // Nth element $everyOther = $collection->nth(2); // [1, 3, 5, 7, 9] $everyThirdStartingAt2 = $collection->nth(3, 2); // [3, 6, 9] ``` ## Checking and Searching The `contains()`, `has()`, `isEmpty()`, `search()`, `every()`, and checking methods verify collection contents. ```php $collection = collect(['apple', 'banana', 'cherry']); // Contains value $hasBanana = $collection->contains('banana'); // true // Contains with callback $hasLongName = $collection->contains(fn($fruit) => strlen($fruit) > 5); // true (banana, cherry) // Check if key exists $data = collect(['name' => 'John', 'age' => 30]); $hasName = $data->has('name'); // true $hasAll = $data->has(['name', 'age']); // true $hasAny = $data->hasAny(['name', 'email']); // true // Check empty/not empty $isEmpty = collect([])->isEmpty(); // true $isNotEmpty = $collection->isNotEmpty(); // true // Search for value (returns key) $key = $collection->search('banana'); // 1 // Search with callback $key = $collection->search(fn($item) => strlen($item) === 6); // Result: 0 (apple has 5, banana has 6) // Every - check if all items pass test $allFruits = $collection->every(fn($item) => is_string($item)); // true // With objects $users = collect([ ['name' => 'John', 'role' => 'admin'], ['name' => 'Jane', 'role' => 'user'], ]); $hasAdmin = $users->contains('role', 'admin'); // true // Sole - get single matching item (throws if 0 or >1) $admins = $users->sole('role', 'admin'); // Returns John's record // FirstOrFail - throws if no match $admin = $users->firstOrFail('role', 'admin'); ``` ## Combining Collections The `merge()`, `concat()`, `combine()`, `union()`, `zip()`, and joining methods combine multiple collections. ```php // Merge collections $first = collect(['a' => 1, 'b' => 2]); $second = collect(['b' => 3, 'c' => 4]); $merged = $first->merge($second); // Result: ['a' => 1, 'b' => 3, 'c' => 4] // Concat (append values) $concat = collect([1, 2])->concat([3, 4]); // Result: [1, 2, 3, 4] // Combine keys with values $keys = collect(['name', 'age']); $values = ['John', 30]; $combined = $keys->combine($values); // Result: ['name' => 'John', 'age' => 30] // Union (preserves original keys) $first = collect([1 => 'a', 2 => 'b']); $union = $first->union([2 => 'c', 3 => 'd']); // Result: [1 => 'a', 2 => 'b', 3 => 'd'] // Zip collections together $names = collect(['Alice', 'Bob']); $ages = [25, 30]; $zipped = $names->zip($ages); // Result: [['Alice', 25], ['Bob', 30]] // Cross join $sizes = collect(['S', 'M', 'L']); $colors = ['red', 'blue']; $crossJoin = $sizes->crossJoin($colors); // Result: [['S','red'],['S','blue'],['M','red'],['M','blue'],['L','red'],['L','blue']] // Diff - items not in given array $diff = collect([1, 2, 3, 4, 5])->diff([2, 4]); // Result: [1, 3, 5] // Intersect - items in both $intersect = collect([1, 2, 3, 4, 5])->intersect([2, 4, 6]); // Result: [2, 4] ``` ## Stack Operations The `push()`, `pop()`, `shift()`, `prepend()`, `pull()` methods manipulate collections like stacks and queues. ```php $collection = collect([1, 2, 3]); // Push - add to end $collection->push(4, 5); // Result: [1, 2, 3, 4, 5] // Pop - remove and return from end $last = $collection->pop(); // 5 // Collection: [1, 2, 3, 4] // Pop multiple $lastTwo = $collection->pop(2); // [4, 3] // Collection: [1, 2] // Shift - remove and return from beginning $first = $collection->shift(); // 1 // Collection: [2] // Prepend - add to beginning $collection->prepend(0); // Collection: [0, 2] // Put - set value at key $collection = collect(['name' => 'John']); $collection->put('age', 30); // Result: ['name' => 'John', 'age' => 30] // Pull - get and remove item $age = $collection->pull('age'); // 30 // Collection: ['name' => 'John'] // Forget - remove by key $collection->forget('name'); // Collection: [] // Get or Put - get existing or add default $collection = collect(['name' => 'John']); $age = $collection->getOrPut('age', 25); // 25 (added) $name = $collection->getOrPut('name', 'Default'); // 'John' (existing) ``` ## Unique and Duplicate Handling The `unique()`, `duplicates()`, and deduplication methods handle duplicate values. ```php $collection = collect([1, 2, 2, 3, 3, 3, 4]); // Get unique values $unique = $collection->unique(); // Result: [1, 2, 3, 4] // Unique by key $users = collect([ ['id' => 1, 'name' => 'John', 'dept' => 'Sales'], ['id' => 2, 'name' => 'Jane', 'dept' => 'Sales'], ['id' => 3, 'name' => 'Bob', 'dept' => 'IT'], ]); $uniqueDepts = $users->unique('dept'); // Result: John (Sales), Bob (IT) // Unique with callback $uniqueByLength = collect(['apple', 'pear', 'banana', 'cherry']) ->unique(fn($item) => strlen($item)); // Result: ['apple', 'pear', 'banana'] (lengths: 5, 4, 6) // Find duplicates $duplicates = collect([1, 2, 2, 3, 3, 3, 4])->duplicates(); // Result: [2 => 2, 4 => 3, 5 => 3] // Duplicates by key $duplicateDepts = $users->duplicates('dept'); // Result: [1 => 'Sales'] ``` ## Flattening and Collapsing The `flatten()`, `collapse()`, `dot()`, `undot()` methods handle nested array structures. ```php // Flatten nested arrays $nested = collect([ ['name' => 'John', 'languages' => ['PHP', 'Python']], ['name' => 'Jane', 'languages' => ['JavaScript', 'Ruby']], ]); $flat = $nested->flatten(); // Result: ['John', 'PHP', 'Python', 'Jane', 'JavaScript', 'Ruby'] // Flatten with depth $flat1 = $nested->flatten(1); // Result: ['John', ['PHP', 'Python'], 'Jane', ['JavaScript', 'Ruby']] // Collapse arrays of arrays $collapsed = collect([[1, 2], [3, 4], [5]])->collapse(); // Result: [1, 2, 3, 4, 5] // Dot notation for nested keys $data = collect([ 'user' => [ 'name' => 'John', 'address' => ['city' => 'NYC', 'zip' => '10001'] ] ]); $dotted = $data->dot(); // Result: ['user.name' => 'John', 'user.address.city' => 'NYC', 'user.address.zip' => '10001'] // Undot - expand dot notation $expanded = collect(['user.name' => 'John', 'user.age' => 30])->undot(); // Result: ['user' => ['name' => 'John', 'age' => 30]] ``` ## LazyCollection for Large Datasets LazyCollection uses PHP generators for memory-efficient processing of large datasets, processing items one at a time. ```php use Illuminate\Support\LazyCollection; // Create from generator function $lazy = LazyCollection::make(function () { for ($i = 1; $i <= 1000000; $i++) { yield $i; } }); // Process without loading all into memory $sum = $lazy->filter(fn($n) => $n % 2 === 0) ->take(1000) ->sum(); // Create from file lines $lazy = LazyCollection::make(function () { $handle = fopen('large-file.csv', 'r'); while (($line = fgets($handle)) !== false) { yield str_getcsv($line); } fclose($handle); }); // Range generator $range = LazyCollection::range(1, 1000000); // Remember/cache values $remembered = $lazy->remember(); // Values are cached as enumerated // Eager load into memory when needed $eager = $lazy->take(100)->eager(); // Throttle iteration $throttled = $lazy->throttle(0.5); // Max 2 items per second // Timeout handling $withTimeout = $lazy->takeUntilTimeout( new DateTime('+5 seconds'), fn($item, $key) => logger('Timed out at: '.$key) ); // Convert to regular collection $collection = $lazy->take(100)->collect(); ``` ## Arr Helper Methods The `Arr` class provides static utility methods for array manipulation with "dot" notation support. ```php use Illuminate\Support\Arr; $data = [ 'user' => [ 'name' => 'John', 'email' => 'john@example.com', 'preferences' => ['theme' => 'dark', 'notifications' => true] ], 'settings' => ['language' => 'en'] ]; // Get with dot notation $name = Arr::get($data, 'user.name'); // 'John' $theme = Arr::get($data, 'user.preferences.theme'); // 'dark' $missing = Arr::get($data, 'user.phone', 'N/A'); // 'N/A' // Set with dot notation Arr::set($data, 'user.phone', '555-1234'); Arr::set($data, 'user.preferences.language', 'en'); // Check existence $hasEmail = Arr::has($data, 'user.email'); // true $hasAny = Arr::hasAny($data, ['user.name', 'user.phone']); // true // Add only if missing Arr::add($data, 'user.role', 'member'); // Adds 'role' Arr::add($data, 'user.name', 'Default'); // Does nothing (exists) // Remove keys Arr::forget($data, 'user.preferences.notifications'); // Get and remove $email = Arr::pull($data, 'user.email'); // Pluck values $users = [ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Jane'], ]; $names = Arr::pluck($users, 'name'); // ['John', 'Jane'] $indexed = Arr::pluck($users, 'name', 'id'); // [1 => 'John', 2 => 'Jane'] // Only/Except specific keys $only = Arr::only($data['user'], ['name', 'email']); $except = Arr::except($data['user'], ['preferences']); // First/Last with callbacks $first = Arr::first([1, 2, 3], fn($n) => $n > 1); // 2 $last = Arr::last([1, 2, 3], fn($n) => $n < 3); // 2 // Flatten and dot $flat = Arr::flatten($data); $dotted = Arr::dot($data); $undotted = Arr::undot(['a.b' => 1, 'a.c' => 2]); // Random elements $random = Arr::random([1, 2, 3, 4, 5]); // Single random $randoms = Arr::random([1, 2, 3, 4, 5], 3); // Array of 3 random // Shuffle and sort $shuffled = Arr::shuffle([1, 2, 3, 4, 5]); $sorted = Arr::sort($users, 'name'); // Query string $query = Arr::query(['name' => 'John', 'page' => 2]); // Result: "name=John&page=2" // Wrap/accessible checks $wrapped = Arr::wrap('value'); // ['value'] $isAccessible = Arr::accessible($data); // true $isList = Arr::isList([1, 2, 3]); // true $isAssoc = Arr::isAssoc(['a' => 1]); // true ``` ## Data Helper Functions Global helper functions for working with nested data structures using "dot" notation. ```php // data_get - retrieve nested values $data = ['user' => ['profile' => ['name' => 'John']]]; $name = data_get($data, 'user.profile.name'); // 'John' // Wildcard support $users = [ ['name' => 'John', 'email' => 'john@example.com'], ['name' => 'Jane', 'email' => 'jane@example.com'], ]; $emails = data_get($users, '*.email'); // Result: ['john@example.com', 'jane@example.com'] // Special segment access $first = data_get($users, '{first}.name'); // 'John' $last = data_get($users, '{last}.name'); // 'Jane' // data_set - set nested values $data = []; data_set($data, 'user.name', 'John'); // Result: ['user' => ['name' => 'John']] // Set with wildcards $users = [['name' => 'John'], ['name' => 'Jane']]; data_set($users, '*.active', true); // All users now have 'active' => true // data_fill - set only if missing $data = ['user' => ['name' => 'John']]; data_fill($data, 'user.name', 'Default'); // No change data_fill($data, 'user.email', 'john@example.com'); // Sets email // data_forget - remove nested values data_forget($data, 'user.email'); // data_has - check nested existence $exists = data_has($data, 'user.name'); // true // value() - resolve closures $result = value(fn() => 'computed'); // 'computed' $result = value('static'); // 'static' // collect() - create collection $collection = collect([1, 2, 3]); // head() and last() - array helpers $first = head([1, 2, 3]); // 1 $last = last([1, 2, 3]); // 3 ``` ## Conditional Methods The `when()`, `unless()`, `whenEmpty()`, `whenNotEmpty()` methods enable conditional method chaining. ```php $collection = collect([1, 2, 3, 4, 5]); // When - execute if condition is true $result = $collection ->when(true, fn($col) => $col->push(6)) ->when(false, fn($col) => $col->push(7)); // Result: [1, 2, 3, 4, 5, 6] // Unless - execute if condition is false $result = $collection ->unless(false, fn($col) => $col->push(6)); // Result: [1, 2, 3, 4, 5, 6] // WhenEmpty / WhenNotEmpty $empty = collect([]); $result = $empty->whenEmpty(fn($col) => $col->push('default')); // Result: ['default'] $notEmpty = collect([1, 2, 3]); $result = $notEmpty->whenNotEmpty(fn($col) => $col->push(4)); // Result: [1, 2, 3, 4] // With default callback $result = collect([]) ->when( false, fn($col) => $col->push('if-true'), fn($col) => $col->push('if-false') ); // Result: ['if-false'] // Practical example $users = collect([/* user data */]); $search = 'admin'; $sortBy = 'name'; $result = $users ->when($search, fn($col, $term) => $col->filter( fn($user) => str_contains($user['name'], $term) )) ->when($sortBy, fn($col, $field) => $col->sortBy($field)); ``` ## Higher-Order Collection Proxies Higher-order proxies allow calling collection methods on each item using property access syntax. ```php $users = collect([ ['name' => 'John', 'roles' => ['admin', 'user']], ['name' => 'Jane', 'roles' => ['user']], ['name' => 'Bob', 'roles' => ['moderator', 'user']], ]); // Higher-order each $users->each->roles; // Accesses 'roles' on each item // Higher-order map $collection = collect([ new class { public function name() { return 'John'; } }, new class { public function name() { return 'Jane'; } }, ]); $names = $collection->map->name(); // Result: ['John', 'Jane'] // Higher-order filter $active = collect([ (object)['name' => 'John', 'active' => true], (object)['name' => 'Jane', 'active' => false], ])->filter->active; // Result: [John] // Higher-order sum $orders = collect([ (object)['total' => 100], (object)['total' => 200], (object)['total' => 150], ]); $sum = $orders->sum->total; // 450 // Chaining with proxies $result = collect([ ['items' => [['price' => 10], ['price' => 20]]], ['items' => [['price' => 30], ['price' => 40]]], ])->flatMap->items->sum->price; // Result: 100 ``` ## JSON and Serialization Methods for converting collections to various formats. ```php $collection = collect([ 'name' => 'John', 'email' => 'john@example.com', 'preferences' => ['theme' => 'dark'], ]); // Convert to array $array = $collection->toArray(); // Convert to JSON $json = $collection->toJson(); // Result: '{"name":"John","email":"john@example.com","preferences":{"theme":"dark"}}' // Pretty JSON $prettyJson = $collection->toPrettyJson(); // All items as array $all = $collection->all(); // Keys and values $keys = $collection->keys(); // ['name', 'email', 'preferences'] $values = $collection->values(); // ['John', 'john@example.com', [...]] // Implode/Join $names = collect(['John', 'Jane', 'Bob']); $string = $names->implode(', '); // 'John, Jane, Bob' $users = collect([ ['name' => 'John'], ['name' => 'Jane'], ]); $nameString = $users->implode('name', ', '); // 'John, Jane' // Join with final glue $string = $names->join(', ', ' and '); // Result: 'John, Jane and Bob' // Count items $count = $collection->count(); // 3 // Count by field $grouped = collect([ ['type' => 'fruit'], ['type' => 'vegetable'], ['type' => 'fruit'], ])->countBy('type'); // Result: ['fruit' => 2, 'vegetable' => 1] ``` Illuminate Collections provides a comprehensive toolkit for manipulating arrays and data structures in PHP applications. Its fluent, chainable API makes complex data transformations readable and maintainable. The library excels at filtering, sorting, grouping, and aggregating data with minimal boilerplate code. The dual collection types (Collection and LazyCollection) offer flexibility for different use cases - eager evaluation for smaller datasets and lazy evaluation for memory-efficient processing of large datasets. Combined with the Arr helper class and global helper functions, developers have a complete solution for array manipulation that integrates seamlessly with any PHP project, whether within the Laravel framework or as a standalone dependency.