From 2f9f18ee58fb1c9c625a82ca4b257cad97e694b0 Mon Sep 17 00:00:00 2001 From: datune Date: Sun, 12 Apr 2020 17:38:26 +0200 Subject: [PATCH] Update collections documentation for L6 upgrade (#449) --- services-collections.md | 1692 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 1582 insertions(+), 110 deletions(-) diff --git a/services-collections.md b/services-collections.md index 42ee7d2a..f79d1486 100644 --- a/services-collections.md +++ b/services-collections.md @@ -3,6 +3,12 @@ - [Introduction](#introduction) - [Creating collections](#creating-collections) - [Available methods](#available-methods) +- [Higher Order Messages](#higher-order-messages) +- [Lazy Collections](#lazy-collections) + - [Introduction](#lazy-collection-introduction) + - [Creating Lazy Collections](#creating-lazy-collections) + - [The Enumerable Contract](#the-enumerable-contract) + - [Lazy Collection Methods](#lazy-collection-methods) ## Introduction @@ -50,15 +56,32 @@ You may select any method from this table to see an example of its usage:
+ [all](#method-all) +[average](#method-average) +[avg](#method-avg) [chunk](#method-chunk) [collapse](#method-collapse) +[collect](#method-collect) +[combine](#method-combine) +[concat](#method-concat) [contains](#method-contains) +[containsStrict](#method-containsstrict) [count](#method-count) +[countBy](#method-countBy) +[crossJoin](#method-crossjoin) +[dd](#method-dd) [diff](#method-diff) +[diffAssoc](#method-diffassoc) +[diffKeys](#method-diffkeys) +[dump](#method-dump) +[duplicates](#method-duplicates) +[duplicatesStrict](#method-duplicatesstrict) [each](#method-each) [filter](#method-filter) [first](#method-first) +[firstWhere](#method-first-where) +[flatMap](#method-flatmap) [flatten](#method-flatten) [flip](#method-flip) [forget](#method-forget) @@ -68,12 +91,29 @@ You may select any method from this table to see an example of its usage: [has](#method-has) [implode](#method-implode) [intersect](#method-intersect) +[intersectByKeys](#method-intersectbykeys) [isEmpty](#method-isempty) +[isNotEmpty](#method-isnotempty) +[join](#method-join) [keyBy](#method-keyby) [keys](#method-keys) [last](#method-last) [map](#method-map) +[mapInto](#method-mapinto) +[mapSpread](#method-mapspread) +[mapToGroups](#method-maptogroups) +[mapWithKeys](#method-mapwithkeys) +[max](#method-max) +[median](#method-median) [merge](#method-merge) +[mergeRecursive](#method-mergerecursive) +[min](#method-min) +[mode](#method-mode) +[nth](#method-nth) +[only](#method-only) +[pad](#method-pad) +[partition](#method-partition) +[pipe](#method-pipe) [pluck](#method-pluck) [pop](#method-pop) [prepend](#method-prepend) @@ -83,25 +123,54 @@ You may select any method from this table to see an example of its usage: [random](#method-random) [reduce](#method-reduce) [reject](#method-reject) +[replace](#method-replace) +[replaceRecursive](#method-replacerecursive) [reverse](#method-reverse) [search](#method-search) [shift](#method-shift) [shuffle](#method-shuffle) +[skip](#method-skip) [slice](#method-slice) +[some](#method-some) [sort](#method-sort) [sortBy](#method-sortby) [sortByDesc](#method-sortbydesc) +[sortKeys](#method-sortkeys) +[sortKeysDesc](#method-sortkeysdesc) [splice](#method-splice) +[split](#method-split) [sum](#method-sum) [take](#method-take) +[tap](#method-tap) +[times](#method-times) [toArray](#method-toarray) [toJson](#method-tojson) [transform](#method-transform) +[union](#method-union) [unique](#method-unique) +[uniqueStrict](#method-uniquestrict) +[unless](#method-unless) +[unlessEmpty](#method-unlessempty) +[unlessNotEmpty](#method-unlessnotempty) +[unwrap](#method-unwrap) [values](#method-values) +[when](#method-when) +[whenEmpty](#method-whenempty) +[whenNotEmpty](#method-whennotempty) [where](#method-where) -[whereLoose](#method-whereloose) +[whereStrict](#method-wherestrict) +[whereBetween](#method-wherebetween) +[whereIn](#method-wherein) +[whereInStrict](#method-whereinstrict) +[whereInstanceOf](#method-whereinstanceof) +[whereNotBetween](#method-wherenotbetween) +[whereNotIn](#method-wherenotin) +[whereNotInStrict](#method-wherenotinstrict) +[whereNotNull](#method-wherenotnull) +[whereNull](#method-wherenull) +[wrap](#method-wrap) [zip](#method-zip) +
@@ -128,6 +197,24 @@ The `all` method simply returns the underlying array represented by the collecti // [1, 2, 3] + +#### `average()` {#collection-method} + +Alias for the [`avg`](#method-avg) method. + + +#### `avg()` {#collection-method} + +The `avg` method returns the [average value](https://en.wikipedia.org/wiki/Average) of a given key: + + $average = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo'); + + // 20 + + $average = collect([1, 1, 2, 4])->avg(); + + // 2 + #### `chunk()` {.collection-method} @@ -163,13 +250,71 @@ The `collapse` method collapses a collection of arrays into a flat collection: $collapsed->all(); // [1, 2, 3, 4, 5, 6, 7, 8, 9] + +#### `combine()` {#collection-method} + +The `combine` method combines the values of the collection, as keys, with the values of another array or collection: + + $collection = collect(['name', 'age']); + + $combined = $collection->combine(['George', 29]); + + $combined->all(); + + // ['name' => 'George', 'age' => 29] + + +#### `collect()` {#collection-method} + +The `collect` method returns a new `Collection` instance with the items currently in the collection: + + $collectionA = collect([1, 2, 3]); + + $collectionB = $collectionA->collect(); + + $collectionB->all(); + + // [1, 2, 3] + +The `collect` method is primarily useful for converting [lazy collections](#lazy-collections) into standard `Collection` instances: + + $lazyCollection = LazyCollection::make(function () { + yield 1; + yield 2; + yield 3; + }); + + $collection = $lazyCollection->collect(); + + get_class($collection); + + // 'Illuminate\Support\Collection' + + $collection->all(); + + // [1, 2, 3] + +> **Tip:** The `collect` method is especially useful when you have an instance of `Enumerable` and need a non-lazy collection instance. Since `collect()` is part of the `Enumerable` contract, you can safely use it to get a `Collection` instance. + + +#### `concat()` {#collection-method} + +The `concat` method appends the given `array` or collection values onto the end of the collection: + + $collection = collect(['John Doe']); + + $concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']); + + $concatenated->all(); + + // ['John Doe', 'Jane Doe', 'Johnny Doe'] -#### `contains()` {.collection-method} +#### `contains()` {#collection-method} The `contains` method determines whether the collection contains a given item: - $collection = new Collection(['name' => 'Desk', 'price' => 100]); + $collection = collect(['name' => 'Desk', 'price' => 100]); $collection->contains('Desk'); @@ -181,7 +326,7 @@ The `contains` method determines whether the collection contains a given item: You may also pass a key / value pair to the `contains` method, which will determine if the given pair exists in the collection: - $collection = new Collection([ + $collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ]); @@ -192,14 +337,21 @@ You may also pass a key / value pair to the `contains` method, which will determ Finally, you may also pass a callback to the `contains` method to perform your own truth test: - $collection = new Collection([1, 2, 3, 4, 5]); + $collection = collect([1, 2, 3, 4, 5]); - $collection->contains(function ($key, $value) { + $collection->contains(function ($value, $key) { return $value > 5; }); // false +The `contains` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`containsStrict`](#method-containsstrict) method to filter using "strict" comparisons. + + +#### `containsStrict()` {#collection-method} + +This method has the same signature as the [`contains`](#method-contains) method; however, all values are compared using "strict" comparisons. + #### `count()` {.collection-method} @@ -211,6 +363,90 @@ The `count` method returns the total number of items in the collection: // 4 + +#### `countBy()` {#collection-method} + +The `countBy` method counts the occurrences of values in the collection. By default, the method counts the occurrences of every element: + + $collection = collect([1, 2, 2, 2, 3]); + + $counted = $collection->countBy(); + + $counted->all(); + + // [1 => 1, 2 => 3, 3 => 1] + +However, you pass a callback to the `countBy` method to count all items by a custom value: + + $collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']); + + $counted = $collection->countBy(function ($email) { + return substr(strrchr($email, "@"), 1); + }); + + $counted->all(); + + // ['gmail.com' => 2, 'yahoo.com' => 1] + + +#### `crossJoin()` {#collection-method} + +The `crossJoin` method cross joins the collection's values among the given arrays or collections, returning a Cartesian product with all possible permutations: + + $collection = collect([1, 2]); + + $matrix = $collection->crossJoin(['a', 'b']); + + $matrix->all(); + + /* + [ + [1, 'a'], + [1, 'b'], + [2, 'a'], + [2, 'b'], + ] + */ + + $collection = collect([1, 2]); + + $matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']); + + $matrix->all(); + + /* + [ + [1, 'a', 'I'], + [1, 'a', 'II'], + [1, 'b', 'I'], + [1, 'b', 'II'], + [2, 'a', 'I'], + [2, 'a', 'II'], + [2, 'b', 'I'], + [2, 'b', 'II'], + ] + */ + + +#### `dd()` {#collection-method} + +The `dd` method dumps the collection's items and ends execution of the script: + + $collection = collect(['John Doe', 'Jane Doe']); + + $collection->dd(); + + /* + Collection { + #items: array:2 [ + 0 => "John Doe" + 1 => "Jane Doe" + ] + } + */ + +If you do not want to stop executing the script, use the [`dump`](#method-dump) method instead. + #### `diff()` {.collection-method} @@ -224,23 +460,118 @@ The `diff` method compares the collection against another collection or a plain // [1, 3, 5] + +#### `diffAssoc()` {#collection-method} + +The `diffAssoc` method compares the collection against another collection or a plain PHP `array` based on its keys and values. This method will return the key / value pairs in the original collection that are not present in the given collection: + + $collection = collect([ + 'color' => 'orange', + 'type' => 'fruit', + 'remain' => 6 + ]); + + $diff = $collection->diffAssoc([ + 'color' => 'yellow', + 'type' => 'fruit', + 'remain' => 3, + 'used' => 6, + ]); + + $diff->all(); + + // ['color' => 'orange', 'remain' => 6] + + +#### `diffKeys()` {#collection-method} + +The `diffKeys` method compares the collection against another collection or a plain PHP `array` based on its keys. This method will return the key / value pairs in the original collection that are not present in the given collection: + + $collection = collect([ + 'one' => 10, + 'two' => 20, + 'three' => 30, + 'four' => 40, + 'five' => 50, + ]); + + $diff = $collection->diffKeys([ + 'two' => 2, + 'four' => 4, + 'six' => 6, + 'eight' => 8, + ]); + + $diff->all(); + + // ['one' => 10, 'three' => 30, 'five' => 50] + + +#### `dump()` {#collection-method} + +The `dump` method dumps the collection's items: + + $collection = collect(['John Doe', 'Jane Doe']); + + $collection->dump(); + + /* + Collection { + #items: array:2 [ + 0 => "John Doe" + 1 => "Jane Doe" + ] + } + */ + +If you want to stop executing the script after dumping the collection, use the [`dd`](#method-dd) method instead. + + +#### `duplicates()` {#collection-method} + +The `duplicates` method retrieves and returns duplicate values from the collection: + + $collection = collect(['a', 'b', 'a', 'c', 'b']); + + $collection->duplicates(); + + // [2 => 'a', 4 => 'b'] + +If the collection contains arrays or objects, you can pass the key of the attributes that you wish to check for duplicate values: + + $employees = collect([ + ['email' => 'abigail@example.com', 'position' => 'Developer'], + ['email' => 'james@example.com', 'position' => 'Designer'], + ['email' => 'victoria@example.com', 'position' => 'Developer'], + ]) + + $employees->duplicates('position'); + + // [2 => 'Developer'] + + +#### `duplicatesStrict()` {#collection-method} + +This method has the same signature as the [`duplicates`](#method-duplicates) method; however, all values are compared using "strict" comparisons. + -#### `each()` {.collection-method} +#### `each()` {#collection-method} -The `each` method iterates over the items in the collection and passes each item to a given callback: +The `each` method iterates over the items in the collection and passes each item to a callback: - $collection = $collection->each(function ($item, $key) { + $collection->each(function ($item, $key) { // }); -Return `false` from your callback to break out of the loop: +If you would like to stop iterating through the items, you may return `false` from your callback: - $collection = $collection->each(function ($item, $key) { + $collection->each(function ($item, $key) { if (/* some condition */) { return false; } }); + #### `every()` {.collection-method} @@ -292,6 +623,53 @@ You may also call the `first` method with no arguments to get the first element // 1 + +#### `firstWhere()` {#collection-method} + +The `firstWhere` method returns the first element in the collection with the given key / value pair: + + $collection = collect([ + ['name' => 'Regena', 'age' => null], + ['name' => 'Linda', 'age' => 14], + ['name' => 'Diego', 'age' => 23], + ['name' => 'Linda', 'age' => 84], + ]); + + $collection->firstWhere('name', 'Linda'); + + // ['name' => 'Linda', 'age' => 14] + +You may also call the `firstWhere` method with an operator: + + $collection->firstWhere('age', '>=', 18); + + // ['name' => 'Diego', 'age' => 23] + +Like the [where](#method-where) method, you may pass one argument to the `firstWhere` method. In this scenario, the `firstWhere` method will return the first item where the given item key's value is "truthy": + + $collection->firstWhere('age'); + + // ['name' => 'Linda', 'age' => 14] + + +#### `flatMap()` {#collection-method} + +The `flatMap` method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items. Then, the array is flattened by a level: + + $collection = collect([ + ['name' => 'Sally'], + ['school' => 'Arkansas'], + ['age' => 28] + ]); + + $flattened = $collection->flatMap(function ($values) { + return array_map('strtoupper', $values); + }); + + $flattened->all(); + + // ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28']; + #### `flatten()` {.collection-method} @@ -468,6 +846,23 @@ The `intersect` method removes any values that are not present in the given `arr As you can see, the resulting collection will preserve the original collection's keys. + +#### `intersectByKeys()` {#collection-method} + +The `intersectByKeys` method removes any keys from the original collection that are not present in the given `array` or collection: + + $collection = collect([ + 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009 + ]); + + $intersect = $collection->intersectByKeys([ + 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011 + ]); + + $intersect->all(); + + // ['type' => 'screen', 'year' => 2009] + #### `isEmpty()` {.collection-method} @@ -477,6 +872,26 @@ The `isEmpty` method returns `true` if the collection is empty; otherwise `false // true + +#### `isNotEmpty()` {#collection-method} + +The `isNotEmpty` method returns `true` if the collection is not empty; otherwise, `false` is returned: + + collect([])->isNotEmpty(); + + // false + + +#### `join()` {#collection-method} + +The `join` method joins the collection's values with a string: + + collect(['a', 'b', 'c'])->join(', '); // 'a, b, c' + collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c' + collect(['a', 'b'])->join(', ', ' and '); // 'a and b' + collect(['a'])->join(', ', ' and '); // 'a' + collect([])->join(', ', ' and '); // '' + #### `keyBy()` {.collection-method} @@ -566,138 +981,400 @@ The `map` method iterates through the collection and passes each value to the gi > **Note:** Like most other collection methods, `map` returns a new collection instance; it does not modify the collection it is called on. If you want to transform the original collection, use the [`transform`](#method-transform) method. - -#### `merge()` {.collection-method} + +#### `mapInto()` {#collection-method} + +The `mapInto()` method iterates over the collection, creating a new instance of the given class by passing the value into the constructor: + + class Currency + { + /** + * Create a new currency instance. + * + * @param string $code + * @return void + */ + function __construct(string $code) + { + $this->code = $code; + } + } -The `merge` method merges the given array into the collection. Any string key in the array matching a string key in the collection will overwrite the value in the collection: + $collection = collect(['USD', 'EUR', 'GBP']); - $collection = new Collection(['product_id' => 1, 'name' => 'Desk']); + $currencies = $collection->mapInto(Currency::class); - $merged = $collection->merge(['price' => 100, 'discount' => false]); + $currencies->all(); - $merged->all(); + // [Currency('USD'), Currency('EUR'), Currency('GBP')] - // ['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false] + +#### `mapSpread()` {#collection-method} -If the given array's keys are numeric, the values will be appended to the end of the collection: +The `mapSpread` method iterates over the collection's items, passing each nested item value into the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items: - $collection = new Collection(['Bookcase', 'Chair']); + $collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - $merged = $collection->merge(['Desk', 'Door']); + $chunks = $collection->chunk(2); - $merged->all(); + $sequence = $chunks->mapSpread(function ($even, $odd) { + return $even + $odd; + }); - // ['Bookcase', 'Chair', 'Desk', 'Door'] + $sequence->all(); - -#### `pluck()` {.collection-method} + // [1, 5, 9, 13, 17] -The `pluck` method retrieves all of the collection values for a given key: + +#### `mapToGroups()` {#collection-method} - $collection = new Collection([ - ['product_id' => 'prod-100', 'name' => 'Chair'], - ['product_id' => 'prod-200', 'name' => 'Desk'], +The `mapToGroups` method groups the collection's items by the given callback. The callback should return an associative array containing a single key / value pair, thus forming a new collection of grouped values: + + $collection = collect([ + [ + 'name' => 'John Doe', + 'department' => 'Sales', + ], + [ + 'name' => 'Jane Doe', + 'department' => 'Sales', + ], + [ + 'name' => 'Johnny Doe', + 'department' => 'Marketing', + ] ]); - $plucked = $collection->pluck('name'); + $grouped = $collection->mapToGroups(function ($item, $key) { + return [$item['department'] => $item['name']]; + }); - $plucked->all(); + $grouped->toArray(); - // ['Chair', 'Desk'] + /* + [ + 'Sales' => ['John Doe', 'Jane Doe'], + 'Marketing' => ['Johnny Doe'], + ] + */ -You may also specify how you wish the resulting collection to be keyed: + $grouped->get('Sales')->all(); - $plucked = $collection->pluck('name', 'product_id'); + // ['John Doe', 'Jane Doe'] - $plucked->all(); + +#### `mapWithKeys()` {#collection-method} - // ['prod-100' => 'Desk', 'prod-200' => 'Chair'] +The `mapWithKeys` method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair: - -#### `pop()` {.collection-method} + $collection = collect([ + [ + 'name' => 'John', + 'department' => 'Sales', + 'email' => 'john@example.com' + ], + [ + 'name' => 'Jane', + 'department' => 'Marketing', + 'email' => 'jane@example.com' + ] + ]); -The `pop` method removes and returns the last item from the collection: + $keyed = $collection->mapWithKeys(function ($item) { + return [$item['email'] => $item['name']]; + }); - $collection = new Collection([1, 2, 3, 4, 5]); + $keyed->all(); - $collection->pop(); + /* + [ + 'john@example.com' => 'John', + 'jane@example.com' => 'Jane', + ] + */ - // 5 + +#### `max()` {#collection-method} - $collection->all(); +The `max` method returns the maximum value of a given key: - // [1, 2, 3, 4] + $max = collect([['foo' => 10], ['foo' => 20]])->max('foo'); - -#### `prepend()` {.collection-method} + // 20 -The `prepend` method adds an item to the beginning of the collection: + $max = collect([1, 2, 3, 4, 5])->max(); - $collection = new Collection([1, 2, 3, 4, 5]); + // 5 - $collection->prepend(0); + +#### `median()` {#collection-method} - $collection->all(); +The `median` method returns the [median value](https://en.wikipedia.org/wiki/Median) of a given key: - // [0, 1, 2, 3, 4, 5] + $median = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo'); - -#### `pull()` {.collection-method} + // 15 -The `pull` method removes and returns an item from the collection by its key: + $median = collect([1, 1, 2, 4])->median(); - $collection = new Collection(['product_id' => 'prod-100', 'name' => 'Desk']); + // 1.5 - $collection->pull('name'); + +#### `merge()` {#collection-method} - // 'Desk' +The `merge` method merges the given array or collection with the original collection. If a string key in the given items matches a string key in the original collection, the given items's value will overwrite the value in the original collection: - $collection->all(); + $collection = collect(['product_id' => 1, 'price' => 100]); - // ['product_id' => 'prod-100'] + $merged = $collection->merge(['price' => 200, 'discount' => false]); - -#### `push()` {.collection-method} + $merged->all(); -The `push` method appends an item to the end of the collection: + // ['product_id' => 1, 'price' => 200, 'discount' => false] - $collection = new Collection([1, 2, 3, 4]); +If the given items's keys are numeric, the values will be appended to the end of the collection: - $collection->push(5); + $collection = collect(['Desk', 'Chair']); - $collection->all(); + $merged = $collection->merge(['Bookcase', 'Door']); - // [1, 2, 3, 4, 5] + $merged->all(); - -#### `put()` {.collection-method} + // ['Desk', 'Chair', 'Bookcase', 'Door'] -The `put` method sets the given key and value in the collection: + +#### `mergeRecursive()` {#collection-method} - $collection = new Collection(['product_id' => 1, 'name' => 'Desk']); +The `mergeRecursive` method merges the given array or collection recursively with the original collection. If a string key in the given items matches a string key in the original collection, then the values for these keys are merged together into an array, and this is done recursively: - $collection->put('price', 100); + $collection = collect(['product_id' => 1, 'price' => 100]); - $collection->all(); + $merged = $collection->mergeRecursive(['product_id' => 2, 'price' => 200, 'discount' => false]); - // ['product_id' => 1, 'name' => 'Desk', 'price' => 100] + $merged->all(); - -#### `random()` {.collection-method} + // ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false] -The `random` method returns a random item from the collection: + +#### `min()` {#collection-method} - $collection = new Collection([1, 2, 3, 4, 5]); +The `min` method returns the minimum value of a given key: - $collection->random(); + $min = collect([['foo' => 10], ['foo' => 20]])->min('foo'); - // 4 - (retrieved randomly) + // 10 -You may optionally pass an integer to `random`. If that integer is more than `1`, a collection of items is returned: + $min = collect([1, 2, 3, 4, 5])->min(); - $random = $collection->random(3); + // 1 - $random->all(); + +#### `mode()` {#collection-method} + +The `mode` method returns the [mode value](https://en.wikipedia.org/wiki/Mode_(statistics)) of a given key: + + $mode = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo'); + + // [10] + + $mode = collect([1, 1, 2, 4])->mode(); + + // [1] + + +#### `nth()` {#collection-method} + +The `nth` method creates a new collection consisting of every n-th element: + + $collection = collect(['a', 'b', 'c', 'd', 'e', 'f']); + + $collection->nth(4); + + // ['a', 'e'] + +You may optionally pass an offset as the second argument: + + $collection->nth(4, 1); + + // ['b', 'f'] + + +#### `only()` {#collection-method} + +The `only` method returns the items in the collection with the specified keys: + + $collection = collect(['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]); + + $filtered = $collection->only(['product_id', 'name']); + + $filtered->all(); + + // ['product_id' => 1, 'name' => 'Desk'] + +For the inverse of `only`, see the [except](#method-except) method. + + +#### `pad()` {#collection-method} + +The `pad` method will fill the array with the given value until the array reaches the specified size. This method behaves like the [array_pad](https://secure.php.net/manual/en/function.array-pad.php) PHP function. + +To pad to the left, you should specify a negative size. No padding will take place if the absolute value of the given size is less than or equal to the length of the array: + + $collection = collect(['A', 'B', 'C']); + + $filtered = $collection->pad(5, 0); + + $filtered->all(); + + // ['A', 'B', 'C', 0, 0] + + $filtered = $collection->pad(-5, 0); + + $filtered->all(); + + // [0, 0, 'A', 'B', 'C'] + + +#### `partition()` {#collection-method} + +The `partition` method may be combined with the `list` PHP function to separate elements that pass a given truth test from those that do not: + + $collection = collect([1, 2, 3, 4, 5, 6]); + + list($underThree, $equalOrAboveThree) = $collection->partition(function ($i) { + return $i < 3; + }); + + $underThree->all(); + + // [1, 2] + + $equalOrAboveThree->all(); + + // [3, 4, 5, 6] + + +#### `pipe()` {#collection-method} + +The `pipe` method passes the collection to the given callback and returns the result: + + $collection = collect([1, 2, 3]); + + $piped = $collection->pipe(function ($collection) { + return $collection->sum(); + }); + + // 6 + + +#### `pluck()` {.collection-method} + +The `pluck` method retrieves all of the collection values for a given key: + + $collection = new Collection([ + ['product_id' => 'prod-100', 'name' => 'Chair'], + ['product_id' => 'prod-200', 'name' => 'Desk'], + ]); + + $plucked = $collection->pluck('name'); + + $plucked->all(); + + // ['Chair', 'Desk'] + +You may also specify how you wish the resulting collection to be keyed: + + $plucked = $collection->pluck('name', 'product_id'); + + $plucked->all(); + + // ['prod-100' => 'Desk', 'prod-200' => 'Chair'] + + +#### `pop()` {.collection-method} + +The `pop` method removes and returns the last item from the collection: + + $collection = new Collection([1, 2, 3, 4, 5]); + + $collection->pop(); + + // 5 + + $collection->all(); + + // [1, 2, 3, 4] + + +#### `prepend()` {.collection-method} + +The `prepend` method adds an item to the beginning of the collection: + + $collection = new Collection([1, 2, 3, 4, 5]); + + $collection->prepend(0); + + $collection->all(); + + // [0, 1, 2, 3, 4, 5] + + +#### `pull()` {.collection-method} + +The `pull` method removes and returns an item from the collection by its key: + + $collection = new Collection(['product_id' => 'prod-100', 'name' => 'Desk']); + + $collection->pull('name'); + + // 'Desk' + + $collection->all(); + + // ['product_id' => 'prod-100'] + + +#### `push()` {.collection-method} + +The `push` method appends an item to the end of the collection: + + $collection = new Collection([1, 2, 3, 4]); + + $collection->push(5); + + $collection->all(); + + // [1, 2, 3, 4, 5] + + +#### `put()` {.collection-method} + +The `put` method sets the given key and value in the collection: + + $collection = new Collection(['product_id' => 1, 'name' => 'Desk']); + + $collection->put('price', 100); + + $collection->all(); + + // ['product_id' => 1, 'name' => 'Desk', 'price' => 100] + + +#### `random()` {.collection-method} + +The `random` method returns a random item from the collection: + + $collection = new Collection([1, 2, 3, 4, 5]); + + $collection->random(); + + // 4 - (retrieved randomly) + +You may optionally pass an integer to `random`. If that integer is more than `1`, a collection of items is returned: + + $random = $collection->random(3); + + $random->all(); // [2, 4, 5] - (retrieved randomly) @@ -739,6 +1416,32 @@ The `reject` method filters the collection using the given callback. The callbac For the inverse of the `reject` method, see the [`filter`](#method-filter) method. + +#### `replace()` {#collection-method} + +The `replace` method behaves similarly to `merge`; however, in addition to overwriting matching items with string keys, the `replace` method will also overwrite items in the collection that have matching numeric keys: + + $collection = collect(['Taylor', 'Abigail', 'James']); + + $replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']); + + $replaced->all(); + + // ['Taylor', 'Victoria', 'James', 'Finn'] + + +#### `replaceRecursive()` {#collection-method} + +This method works like `replace`, but it will recur into arrays and apply the same replacement process to the inner values: + + $collection = collect(['Taylor', 'Abigail', ['James', 'Victoria', 'Finn']]); + + $replaced = $collection->replaceRecursive(['Charlie', 2 => [1 => 'King']]); + + $replaced->all(); + + // ['Charlie', 'Abigail', ['James', 'King', 'Finn']] + #### `reverse()` {.collection-method} @@ -805,12 +1508,26 @@ The `shuffle` method randomly shuffles the items in the collection: // [3, 2, 5, 1, 4] (generated randomly) + + +#### `skip()` {#collection-method} + +The `skip` method returns a new collection, without the first given amount of items: + + $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + + $collection = $collection->skip(4); + + $collection->all(); + + // [5, 6, 7, 8, 9, 10] + -#### `slice()` {.collection-method} +#### `slice()` {#collection-method} The `slice` method returns a slice of the collection starting at the given index: - $collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $slice = $collection->slice(4); @@ -826,7 +1543,12 @@ If you would like to limit the size of the returned slice, pass the desired size // [5, 6] -The returned slice will have new, numerically indexed keys. If you wish to preserve the original keys, pass `true` as the third argument to the method. +The returned slice will preserve keys by default. If you do not wish to preserve the original keys, you can use the [`values`](#method-values) method to reindex them. + + +#### `some()` {#collection-method} + +Alias for the [`contains`](#method-contains) method. #### `sort()` {.collection-method} @@ -899,6 +1621,79 @@ You can also pass your own callback to determine how to sort the collection valu This method has the same signature as the [`sortBy`](#method-sortby) method, but will sort the collection in the opposite order. + +#### `sortKeys()` {#collection-method} + +The `sortKeys` method sorts the collection by the keys of the underlying associative array: + + $collection = collect([ + 'id' => 22345, + 'first' => 'John', + 'last' => 'Doe', + ]); + + $sorted = $collection->sortKeys(); + + $sorted->all(); + + /* + [ + 'first' => 'John', + 'id' => 22345, + 'last' => 'Doe', + ] + */ + + +#### `sortKeysDesc()` {#collection-method} + +This method has the same signature as the [`sortKeys`](#method-sortkeys) method, but will sort the collection in the opposite order. + + +#### `splice()` {#collection-method} + +The `splice` method removes and returns a slice of items starting at the specified index: + + $collection = collect([1, 2, 3, 4, 5]); + + $chunk = $collection->splice(2); + + $chunk->all(); + + // [3, 4, 5] + + $collection->all(); + + // [1, 2] + +You may pass a second argument to limit the size of the resulting chunk: + + $collection = collect([1, 2, 3, 4, 5]); + + $chunk = $collection->splice(2, 1); + + $chunk->all(); + + // [3] + + $collection->all(); + + // [1, 2, 4, 5] + +In addition, you can pass a third argument containing the new items to replace the items removed from the collection: + + $collection = collect([1, 2, 3, 4, 5]); + + $chunk = $collection->splice(2, 1, [10, 11]); + + $chunk->all(); + + // [3] + + $collection->all(); + + // [1, 2, 10, 11, 4, 5] + #### `splice()` {.collection-method} @@ -944,6 +1739,19 @@ In addition, you can pass a third argument containing the new items to replace t // [1, 2, 10, 11, 4, 5] + +#### `split()` {#collection-method} + +The `split` method breaks a collection into the given number of groups: + + $collection = collect([1, 2, 3, 4, 5]); + + $groups = $collection->split(3); + + $groups->toArray(); + + // [[1, 2], [3, 4], [5]] + #### `sum()` {.collection-method} @@ -1001,19 +1809,62 @@ You may also pass a negative integer to take the specified amount of items from // [4, 5] - -#### `toArray()` {.collection-method} + +#### `tap()` {#collection-method} -The `toArray` method converts the collection into a plain PHP `array`. If the collection's values are [database models](../database/model), the models will also be converted to arrays: +The `tap` method passes the collection to the given callback, allowing you to "tap" into the collection at a specific point and do something with the items while not affecting the collection itself: - $collection = new Collection(['name' => 'Desk', 'price' => 200]); + collect([2, 4, 3, 1, 5]) + ->sort() + ->tap(function ($collection) { + Log::debug('Values after sorting', $collection->values()->toArray()); + }) + ->shift(); - $collection->toArray(); + // 1 - /* - [ - ['name' => 'Desk', 'price' => 200], - ] + +#### `times()` {#collection-method} + +The static `times` method creates a new collection by invoking the callback a given amount of times: + + $collection = Collection::times(10, function ($number) { + return $number * 9; + }); + + $collection->all(); + + // [9, 18, 27, 36, 45, 54, 63, 72, 81, 90] + +This method can be useful when combined with factories to create [Eloquent](/docs/{{version}}/eloquent) models: + + $categories = Collection::times(3, function ($number) { + return factory(Category::class)->create(['name' => "Category No. $number"]); + }); + + $categories->all(); + + /* + [ + ['id' => 1, 'name' => 'Category No. 1'], + ['id' => 2, 'name' => 'Category No. 2'], + ['id' => 3, 'name' => 'Category No. 3'], + ] + */ + + +#### `toArray()` {.collection-method} + +The `toArray` method converts the collection into a plain PHP `array`. If the collection's values are [database models](../database/model), the models will also be converted to arrays: + + $collection = new Collection(['name' => 'Desk', 'price' => 200]); + + $collection->toArray(); + + /* + [ + ['name' => 'Desk', 'price' => 200], + ] */ > **Note:** `toArray` also converts all of its nested objects to an array. If you want to get the underlying array as is, use the [`all`](#method-all) method instead. @@ -1046,12 +1897,25 @@ The `transform` method iterates over the collection and calls the given callback > **Note:** Unlike most other collection methods, `transform` modifies the collection itself. If you wish to create a new collection instead, use the [`map`](#method-map) method. + +#### `union()` {#collection-method} + +The `union` method adds the given array to the collection. If the given array contains keys that are already in the original collection, the original collection's values will be preferred: + + $collection = collect([1 => ['a'], 2 => ['b']]); + + $union = $collection->union([3 => ['c'], 1 => ['b']]); + + $union->all(); + + // [1 => ['a'], 2 => ['b'], 3 => ['c']] + -#### `unique()` {.collection-method} +#### `unique()` {#collection-method} -The `unique` method returns all of the unique items in the collection: +The `unique` method returns all of the unique items in the collection. The returned collection keeps the original array keys, so in this example we'll use the [`values`](#method-values) method to reset the keys to consecutively numbered indexes: - $collection = new Collection([1, 1, 2, 2, 3, 4, 2]); + $collection = collect([1, 1, 2, 2, 3, 4, 2]); $unique = $collection->unique(); @@ -1059,11 +1923,9 @@ The `unique` method returns all of the unique items in the collection: // [1, 2, 3, 4] -The returned collection keeps the original array keys. In this example we used the [`values`](#method-values) method to reset the keys to consecutively numbered indexes. - When dealing with nested arrays or objects, you may specify the key used to determine uniqueness: - $collection = new Collection([ + $collection = collect([ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], @@ -1099,6 +1961,62 @@ You may also pass your own callback to determine item uniqueness: ] */ +The `unique` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`uniqueStrict`](#method-uniquestrict) method to filter using "strict" comparisons. + + +#### `uniqueStrict()` {#collection-method} + +This method has the same signature as the [`unique`](#method-unique) method; however, all values are compared using "strict" comparisons. + + +#### `unless()` {#collection-method} + +The `unless` method will execute the given callback unless the first argument given to the method evaluates to `true`: + + $collection = collect([1, 2, 3]); + + $collection->unless(true, function ($collection) { + return $collection->push(4); + }); + + $collection->unless(false, function ($collection) { + return $collection->push(5); + }); + + $collection->all(); + + // [1, 2, 3, 5] + +For the inverse of `unless`, see the [`when`](#method-when) method. + + +#### `unlessEmpty()` {#collection-method} + +Alias for the [`whenNotEmpty`](#method-whennotempty) method. + + +#### `unlessNotEmpty()` {#collection-method} + +Alias for the [`whenEmpty`](#method-whenempty) method. + + +#### `unwrap()` {#collection-method} + +The static `unwrap` method returns the collection's underlying items from the given value when applicable: + + Collection::unwrap(collect('John Doe')); + + // ['John Doe'] + + Collection::unwrap(['John Doe']); + + // ['John Doe'] + + Collection::unwrap('John Doe'); + + // 'John Doe' + + #### `values()` {.collection-method} @@ -1119,12 +2037,116 @@ The `values` method returns a new collection with the keys reset to consecutive 1 => ['product' => 'Desk', 'price' => 200], ] */ + + +#### `when()` {#collection-method} + +The `when` method will execute the given callback when the first argument given to the method evaluates to `true`: + + $collection = collect([1, 2, 3]); + + $collection->when(true, function ($collection) { + return $collection->push(4); + }); + + $collection->when(false, function ($collection) { + return $collection->push(5); + }); + + $collection->all(); + + // [1, 2, 3, 4] + +For the inverse of `when`, see the [`unless`](#method-unless) method. + + +#### `whenEmpty()` {#collection-method} + +The `whenEmpty` method will execute the given callback when the collection is empty: + + $collection = collect(['michael', 'tom']); + + $collection->whenEmpty(function ($collection) { + return $collection->push('adam'); + }); + + $collection->all(); + + // ['michael', 'tom'] + + + $collection = collect(); + + $collection->whenEmpty(function ($collection) { + return $collection->push('adam'); + }); + + $collection->all(); + + // ['adam'] + + + $collection = collect(['michael', 'tom']); + + $collection->whenEmpty(function ($collection) { + return $collection->push('adam'); + }, function ($collection) { + return $collection->push('taylor'); + }); + + $collection->all(); + + // ['michael', 'tom', 'taylor'] + +For the inverse of `whenEmpty`, see the [`whenNotEmpty`](#method-whennotempty) method. + + +#### `whenNotEmpty()` {#collection-method} + +The `whenNotEmpty` method will execute the given callback when the collection is not empty: + + $collection = collect(['michael', 'tom']); + + $collection->whenNotEmpty(function ($collection) { + return $collection->push('adam'); + }); + + $collection->all(); + + // ['michael', 'tom', 'adam'] + + + $collection = collect(); + + $collection->whenNotEmpty(function ($collection) { + return $collection->push('adam'); + }); + + $collection->all(); + + // [] + + + $collection = collect(); + + $collection->whenNotEmpty(function ($collection) { + return $collection->push('adam'); + }, function ($collection) { + return $collection->push('taylor'); + }); + + $collection->all(); + + // ['taylor'] + +For the inverse of `whenNotEmpty`, see the [`whenEmpty`](#method-whenempty) method. + -#### `where()` {.collection-method} +#### `where()` {#collection-method} The `where` method filters the collection by a given key / value pair: - $collection = new Collection([ + $collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], @@ -1136,28 +2158,478 @@ The `where` method filters the collection by a given key / value pair: $filtered->all(); /* - [ - ['product' => 'Chair', 'price' => 100], - ['product' => 'Door', 'price' => 100], - ] + [ + ['product' => 'Chair', 'price' => 100], + ['product' => 'Door', 'price' => 100], + ] */ The `where` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereStrict`](#method-wherestrict) method to filter using "strict" comparisons. +Optionally, you may pass a comparison operator as the second parameter. + + $collection = collect([ + ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], + ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], + ['name' => 'Sue', 'deleted_at' => null], + ]); + + $filtered = $collection->where('deleted_at', '!=', null); + + $filtered->all(); + + /* + [ + ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], + ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], + ] + */ + -#### `whereStrict()` {.collection-method} +#### `whereStrict()` {#collection-method} This method has the same signature as the [`where`](#method-where) method; however, all values are compared using "strict" comparisons. + +#### `whereBetween()` {#collection-method} + +The `whereBetween` method filters the collection within a given range: + + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 80], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Pencil', 'price' => 30], + ['product' => 'Door', 'price' => 100], + ]); + + $filtered = $collection->whereBetween('price', [100, 200]); + + $filtered->all(); + + /* + [ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Door', 'price' => 100], + ] + */ + + +#### `whereIn()` {#collection-method} + +The `whereIn` method filters the collection by a given key / value contained within the given array: + + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 100], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Door', 'price' => 100], + ]); + + $filtered = $collection->whereIn('price', [150, 200]); + + $filtered->all(); + + /* + [ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Bookcase', 'price' => 150], + ] + */ + +The `whereIn` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereInStrict`](#method-whereinstrict) method to filter using "strict" comparisons. + + +#### `whereInStrict()` {#collection-method} + +This method has the same signature as the [`whereIn`](#method-wherein) method; however, all values are compared using "strict" comparisons. + + +#### `whereInstanceOf()` {#collection-method} + +The `whereInstanceOf` method filters the collection by a given class type: + + use App\User; + use App\Post; + + $collection = collect([ + new User, + new User, + new Post, + ]); + + $filtered = $collection->whereInstanceOf(User::class); + + $filtered->all(); + + // [App\User, App\User] + + +#### `whereNotBetween()` {#collection-method} + +The `whereNotBetween` method filters the collection within a given range: + + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 80], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Pencil', 'price' => 30], + ['product' => 'Door', 'price' => 100], + ]); + + $filtered = $collection->whereNotBetween('price', [100, 200]); + + $filtered->all(); + + /* + [ + ['product' => 'Chair', 'price' => 80], + ['product' => 'Pencil', 'price' => 30], + ] + */ + + +#### `whereNotIn()` {#collection-method} + +The `whereNotIn` method filters the collection by a given key / value not contained within the given array: + + $collection = collect([ + ['product' => 'Desk', 'price' => 200], + ['product' => 'Chair', 'price' => 100], + ['product' => 'Bookcase', 'price' => 150], + ['product' => 'Door', 'price' => 100], + ]); + + $filtered = $collection->whereNotIn('price', [150, 200]); + + $filtered->all(); + + /* + [ + ['product' => 'Chair', 'price' => 100], + ['product' => 'Door', 'price' => 100], + ] + */ + +The `whereNotIn` method uses "loose" comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the [`whereNotInStrict`](#method-wherenotinstrict) method to filter using "strict" comparisons. + + +#### `whereNotInStrict()` {#collection-method} + +This method has the same signature as the [`whereNotIn`](#method-wherenotin) method; however, all values are compared using "strict" comparisons. + + +#### `whereNotNull()` {#collection-method} + +The `whereNotNull` method filters items where the given key is not null: + + $collection = collect([ + ['name' => 'Desk'], + ['name' => null], + ['name' => 'Bookcase'], + ]); + + $filtered = $collection->whereNotNull('name'); + + $filtered->all(); + + /* + [ + ['name' => 'Desk'], + ['name' => 'Bookcase'], + ] + */ + + +#### `whereNull()` {#collection-method} + +The `whereNull` method filters items where the given key is null: + + $collection = collect([ + ['name' => 'Desk'], + ['name' => null], + ['name' => 'Bookcase'], + ]); + + $filtered = $collection->whereNull('name'); + + $filtered->all(); + + /* + [ + ['name' => null], + ] + */ + + + +#### `wrap()` {#collection-method} + +The static `wrap` method wraps the given value in a collection when applicable: + + $collection = Collection::wrap('John Doe'); + + $collection->all(); + + // ['John Doe'] + + $collection = Collection::wrap(['John Doe']); + + $collection->all(); + + // ['John Doe'] + + $collection = Collection::wrap(collect('John Doe')); + + $collection->all(); + + // ['John Doe'] + -#### `zip()` {.collection-method} +#### `zip()` {#collection-method} -The `zip` method merges together the values of the given array with the values of the collection at the corresponding index: +The `zip` method merges together the values of the given array with the values of the original collection at the corresponding index: - $collection = new Collection(['Chair', 'Desk']); + $collection = collect(['Chair', 'Desk']); $zipped = $collection->zip([100, 200]); $zipped->all(); // [['Chair', 100], ['Desk', 200]] + + +## Higher Order Messages + +Collections also provide support for "higher order messages", which are short-cuts for performing common actions on collections. The collection methods that provide higher order messages are: [`average`](#method-average), [`avg`](#method-avg), [`contains`](#method-contains), [`each`](#method-each), [`every`](#method-every), [`filter`](#method-filter), [`first`](#method-first), [`flatMap`](#method-flatmap), [`groupBy`](#method-groupby), [`keyBy`](#method-keyby), [`map`](#method-map), [`max`](#method-max), [`min`](#method-min), [`partition`](#method-partition), [`reject`](#method-reject), [`some`](#method-some), [`sortBy`](#method-sortby), [`sortByDesc`](#method-sortbydesc), [`sum`](#method-sum), and [`unique`](#method-unique). + +Each higher order message can be accessed as a dynamic property on a collection instance. For instance, let's use the `each` higher order message to call a method on each object within a collection: + + $users = User::where('votes', '>', 500)->get(); + + $users->each->markAsVip(); + +Likewise, we can use the `sum` higher order message to gather the total number of "votes" for a collection of users: + + $users = User::where('group', 'Development')->get(); + + return $users->sum->votes; + + +## Lazy Collections + + +### Introduction + +> **Note:** Before learning more about October's lazy collections, take some time to familiarize yourself with [PHP generators](https://www.php.net/manual/en/language.generators.overview.php). + +To supplement the already powerful `Collection` class, the `LazyCollection` class leverages PHP's [generators](https://www.php.net/manual/en/language.generators.overview.php) to allow you to work with very large datasets while keeping memory usage low. + +For example, imagine your application needs to process a multi-gigabyte log file while taking advantage of October's collection methods to parse the logs. Instead of reading the entire file into memory at once, lazy collections may be used to keep only a small part of the file in memory at a given time: + + use App\LogEntry; + use Illuminate\Support\LazyCollection; + + LazyCollection::make(function () { + $handle = fopen('log.txt', 'r'); + + while (($line = fgets($handle)) !== false) { + yield $line; + } + })->chunk(4)->map(function ($lines) { + return LogEntry::fromLines($lines); + })->each(function (LogEntry $logEntry) { + // Process the log entry... + }); + +Or, imagine you need to iterate through 10,000 Eloquent models. When using traditional October collections, all 10,000 Eloquent models must be loaded into memory at the same time: + + $users = App\User::all()->filter(function ($user) { + return $user->id > 500; + }); + +However, the query builder's `cursor` method returns a `LazyCollection` instance. This allows you to still only run a single query against the database but also only keep one Eloquent model loaded in memory at a time. In this example, the `filter` callback is not executed until we actually iterate over each user individually, allowing for a drastic reduction in memory usage: + + $users = App\User::cursor()->filter(function ($user) { + return $user->id > 500; + }); + + foreach ($users as $user) { + echo $user->id; + } + + +### Creating Lazy Collections + +To create a lazy collection instance, you should pass a PHP generator function to the collection's `make` method: + + use Illuminate\Support\LazyCollection; + + LazyCollection::make(function () { + $handle = fopen('log.txt', 'r'); + + while (($line = fgets($handle)) !== false) { + yield $line; + } + }); + + +### The Enumerable Contract + +Almost all methods available on the `Collection` class are also available on the `LazyCollection` class. Both of these classes implement the `Illuminate\Support\Enumerable` contract, which defines the following methods: + +
+ +[all](#method-all) +[average](#method-average) +[avg](#method-avg) +[chunk](#method-chunk) +[collapse](#method-collapse) +[collect](#method-collect) +[combine](#method-combine) +[concat](#method-concat) +[contains](#method-contains) +[containsStrict](#method-containsstrict) +[count](#method-count) +[countBy](#method-countBy) +[crossJoin](#method-crossjoin) +[dd](#method-dd) +[diff](#method-diff) +[diffAssoc](#method-diffassoc) +[diffKeys](#method-diffkeys) +[dump](#method-dump) +[duplicates](#method-duplicates) +[duplicatesStrict](#method-duplicatesstrict) +[each](#method-each) +[eachSpread](#method-eachspread) +[every](#method-every) +[except](#method-except) +[filter](#method-filter) +[first](#method-first) +[firstWhere](#method-first-where) +[flatMap](#method-flatmap) +[flatten](#method-flatten) +[flip](#method-flip) +[forPage](#method-forpage) +[get](#method-get) +[groupBy](#method-groupby) +[has](#method-has) +[implode](#method-implode) +[intersect](#method-intersect) +[intersectByKeys](#method-intersectbykeys) +[isEmpty](#method-isempty) +[isNotEmpty](#method-isnotempty) +[join](#method-join) +[keyBy](#method-keyby) +[keys](#method-keys) +[last](#method-last) +[macro](#method-macro) +[make](#method-make) +[map](#method-map) +[mapInto](#method-mapinto) +[mapSpread](#method-mapspread) +[mapToGroups](#method-maptogroups) +[mapWithKeys](#method-mapwithkeys) +[max](#method-max) +[median](#method-median) +[merge](#method-merge) +[mergeRecursive](#method-mergerecursive) +[min](#method-min) +[mode](#method-mode) +[nth](#method-nth) +[only](#method-only) +[pad](#method-pad) +[partition](#method-partition) +[pipe](#method-pipe) +[pluck](#method-pluck) +[random](#method-random) +[reduce](#method-reduce) +[reject](#method-reject) +[replace](#method-replace) +[replaceRecursive](#method-replacerecursive) +[reverse](#method-reverse) +[search](#method-search) +[shuffle](#method-shuffle) +[skip](#method-skip) +[slice](#method-slice) +[some](#method-some) +[sort](#method-sort) +[sortBy](#method-sortby) +[sortByDesc](#method-sortbydesc) +[sortKeys](#method-sortkeys) +[sortKeysDesc](#method-sortkeysdesc) +[split](#method-split) +[sum](#method-sum) +[take](#method-take) +[tap](#method-tap) +[times](#method-times) +[toArray](#method-toarray) +[toJson](#method-tojson) +[union](#method-union) +[unique](#method-unique) +[uniqueStrict](#method-uniquestrict) +[unless](#method-unless) +[unlessEmpty](#method-unlessempty) +[unlessNotEmpty](#method-unlessnotempty) +[unwrap](#method-unwrap) +[values](#method-values) +[when](#method-when) +[whenEmpty](#method-whenempty) +[whenNotEmpty](#method-whennotempty) +[where](#method-where) +[whereStrict](#method-wherestrict) +[whereBetween](#method-wherebetween) +[whereIn](#method-wherein) +[whereInStrict](#method-whereinstrict) +[whereInstanceOf](#method-whereinstanceof) +[whereNotBetween](#method-wherenotbetween) +[whereNotIn](#method-wherenotin) +[whereNotInStrict](#method-wherenotinstrict) +[wrap](#method-wrap) +[zip](#method-zip) + +
+ +> **Note:** Methods that mutate the collection (such as `shift`, `pop`, `prepend` etc.) are _not_ available on the `LazyCollection` class. + + +### Lazy Collection Methods + +In addition to the methods defined in the `Enumerable` contract, the `LazyCollection` class contains the following methods: + + +#### `tapEach()` {#collection-method} + +While the `each` method calls the given callback for each item in the collection right away, the `tapEach` method only calls the given callback as the items are being pulled out of the list one by one: + + $lazyCollection = LazyCollection::times(INF)->tapEach(function ($value) { + dump($value); + }); + + // Nothing has been dumped so far... + + $array = $lazyCollection->take(3)->all(); + + // 1 + // 2 + // 3 + + +#### `remember()` {#collection-method} + +The `remember` method returns a new lazy collection that will remember any values that have already been enumerated and will not retrieve them again when the collection is enumerated again: + + $users = User::cursor()->remember(); + + // No query has been executed yet... + + $users->take(5)->all(); + + // The query has been executed and the first 5 users have been hydrated from the database... + + $users->take(20)->all(); + + // First 5 users come from the collection's cache... The rest are hydrated from the database... + +