Collection
簡介
Illuminate\Support\Collection
類別為處理陣列資料提供了一個流暢且便利的包裝。舉例來說,看看下列程式碼。我們會使用 collect
輔助函式來自陣列建立一個新的 Collection 實體,然後在每個元素上執行 strtoupper
函式,並移除所有空元素:
1$collection = collect(['taylor', 'abigail', null])->map(function (string $name) {2 return strtoupper($name);3})->reject(function (string $name) {4 return empty($name);5});
1$collection = collect(['taylor', 'abigail', null])->map(function (string $name) {2 return strtoupper($name);3})->reject(function (string $name) {4 return empty($name);5});
如你所見,Collection
類別能讓你將其方法串在一起呼叫,以流暢地在底層的陣列上進行 Map 與 Reduce 處理。通常來說,Collection 是不可變的(Immutable),這代表每個 Collection
方法都會回傳一個全新的 Collection
實體。
建立 Collection
就像上面提到的一樣,collect
輔助函式會為給定的陣列回傳一個新的 Illuminate\Support\Collection
實體。因此,建立 Collection 就這麼簡單:
1$collection = collect([1, 2, 3]);
1$collection = collect([1, 2, 3]);
Eloquent 查詢的結果總會回傳為 Collection
實體。
擴充 Collection
Collection 是「Macroable (可巨集)」的,這代表我們可以在執行階段往 Collection
增加額外的方法。Illuminate\Support\Collection
類別的 macro
方法接收一個閉包,該閉包會在 Macro 被呼叫時執行。Macro 閉包也能像真正的 Collection 類別方法一樣,通過 $this
來存取該 Collection 的其他方法。舉例來說,下列程式碼會往 Collection
類別內新增一個 toUpper
方法:
1use Illuminate\Support\Collection;2use Illuminate\Support\Str;34Collection::macro('toUpper', function () {5 return $this->map(function (string $value) {6 return Str::upper($value);7 });8});910$collection = collect(['first', 'second']);1112$upper = $collection->toUpper();1314// ['FIRST', 'SECOND']
1use Illuminate\Support\Collection;2use Illuminate\Support\Str;34Collection::macro('toUpper', function () {5 return $this->map(function (string $value) {6 return Str::upper($value);7 });8});910$collection = collect(['first', 'second']);1112$upper = $collection->toUpper();1314// ['FIRST', 'SECOND']
一般來說,Collection Macro 的宣告應放置於某個 Service Provider 的 boot
方法內。
Macro 引數
若有需要,也可以定義接受額外引數的 Macro:
1use Illuminate\Support\Collection;2use Illuminate\Support\Facades\Lang;34Collection::macro('toLocale', function (string $locale) {5 return $this->map(function (string $value) use ($locale) {6 return Lang::get($value, [], $locale);7 });8});910$collection = collect(['first', 'second']);1112$translated = $collection->toLocale('es');
1use Illuminate\Support\Collection;2use Illuminate\Support\Facades\Lang;34Collection::macro('toLocale', function (string $locale) {5 return $this->map(function (string $value) use ($locale) {6 return Lang::get($value, [], $locale);7 });8});910$collection = collect(['first', 'second']);1112$translated = $collection->toLocale('es');
可用方法
在 Collection 說明文件剩下的一大部分,我們會討論 Collection
類別內可用的各個方法。請記住,這裡所有的方法都可以互相串接使用,以流利地操作底層的陣列。此外,幾乎所有的函式都會回傳一個新的 Collection
實體,讓你可以在有需要的時候保留原始的 Collection 拷貝:
all average avg chunk chunkWhile collapse collect combine concat contains containsOneItem containsStrict count countBy crossJoin dd diff diffAssoc diffKeys doesntContain dump duplicates duplicatesStrict each eachSpread every except filter first firstOrFail firstWhere flatMap flatten flip forget forPage get groupBy has hasAny implode intersect intersectByKeys isEmpty isNotEmpty join keyBy keys last lazy macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode nth only pad partition pipe pipeInto pipeThrough pluck pop prepend pull push put random range reduce reduceSpread reject replace replaceRecursive reverse search shift shuffle skip skipUntil skipWhile slice sliding sole some sort sortBy sortByDesc sortDesc sortKeys sortKeysDesc sortKeysUsing splice split splitIn sum take takeUntil takeWhile tap times toArray toJson transform undot union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap value values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict whereNotNull whereNull wrap zip
方法列表
all()
all
方法會回傳該 Collection 所代表的底層陣列:
1collect([1, 2, 3])->all();23// [1, 2, 3]
1collect([1, 2, 3])->all();23// [1, 2, 3]
average()
avg
方法的別名。
avg()
avg
方法會回傳給定索引鍵的平均值:
1$average = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->avg('foo');78// 20910$average = collect([1, 1, 2, 4])->avg();1112// 2
1$average = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->avg('foo');78// 20910$average = collect([1, 1, 2, 4])->avg();1112// 2
chunk()
chunk
方法會將該 Collection 以給定的大小拆分為多個較小的 Collection:
1$collection = collect([1, 2, 3, 4, 5, 6, 7]);23$chunks = $collection->chunk(4);45$chunks->all();67// [[1, 2, 3, 4], [5, 6, 7]]
1$collection = collect([1, 2, 3, 4, 5, 6, 7]);23$chunks = $collection->chunk(4);45$chunks->all();67// [[1, 2, 3, 4], [5, 6, 7]]
此方法特別適合用在 View 內,配合如 Bootstrap 等網格系統一起使用。舉例來說,假設我們有一個 Eloquent 模型的 Collection 想要在網格上顯示:
1@foreach ($products->chunk(3) as $chunk)2 <div class="row">3 @foreach ($chunk as $product)4 <div class="col-xs-4">{{ $product->name }}</div>5 @endforeach6 </div>7@endforeach
1@foreach ($products->chunk(3) as $chunk)2 <div class="row">3 @foreach ($chunk as $product)4 <div class="col-xs-4">{{ $product->name }}</div>5 @endforeach6 </div>7@endforeach
chunkWhile()
chunkWhile
方法會依照給定回呼的取值結果來將 Collection 拆分為多個更小的 Collection。傳入閉包的 $chunk
變數可用來檢視上一個元素:
1$collection = collect(str_split('AABBCCCD'));23$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {4 return $value === $chunk->last();5});67$chunks->all();89// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
1$collection = collect(str_split('AABBCCCD'));23$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {4 return $value === $chunk->last();5});67$chunks->all();89// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
collapse()
collapse
方法可以將多個陣列合併為單一的扁平 (Flat) Collection:
1$collection = collect([2 [1, 2, 3],3 [4, 5, 6],4 [7, 8, 9],5]);67$collapsed = $collection->collapse();89$collapsed->all();1011// [1, 2, 3, 4, 5, 6, 7, 8, 9]
1$collection = collect([2 [1, 2, 3],3 [4, 5, 6],4 [7, 8, 9],5]);67$collapsed = $collection->collapse();89$collapsed->all();1011// [1, 2, 3, 4, 5, 6, 7, 8, 9]
collect()
collect
方法會回傳一個包含目前 Collection 內項目的新 Collection
實體:
1$collectionA = collect([1, 2, 3]);23$collectionB = $collectionA->collect();45$collectionB->all();67// [1, 2, 3]
1$collectionA = collect([1, 2, 3]);23$collectionB = $collectionA->collect();45$collectionB->all();67// [1, 2, 3]
collect
方法特別適合用來將 Lazy Collection 轉換為標準 Collection
實體:
1$lazyCollection = LazyCollection::make(function () {2 yield 1;3 yield 2;4 yield 3;5});67$collection = $lazyCollection->collect();89get_class($collection);1011// 'Illuminate\Support\Collection'1213$collection->all();1415// [1, 2, 3]
1$lazyCollection = LazyCollection::make(function () {2 yield 1;3 yield 2;4 yield 3;5});67$collection = $lazyCollection->collect();89get_class($collection);1011// 'Illuminate\Support\Collection'1213$collection->all();1415// [1, 2, 3]
collect
方法特別適合用於如有 Enumerable
實體且需要一個非 Lazy Collection 的實體。由於 collect()
是 Enumerable
Contract 的一部分,因此我們可以安全地使用該方法來取得 Collection
實體。
combine()
combine
可用來將 Collection 的值作為索引鍵來與作為值的另一個陣列或 Collection 進行合併:
1$collection = collect(['name', 'age']);23$combined = $collection->combine(['George', 29]);45$combined->all();67// ['name' => 'George', 'age' => 29]
1$collection = collect(['name', 'age']);23$combined = $collection->combine(['George', 29]);45$combined->all();67// ['name' => 'George', 'age' => 29]
concat()
concat
方法會將給定的 array
或 Collection 的值附加到另一個 Collection 的末端:
1$collection = collect(['John Doe']);23$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);45$concatenated->all();67// ['John Doe', 'Jane Doe', 'Johnny Doe']
1$collection = collect(['John Doe']);23$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);45$concatenated->all();67// ['John Doe', 'Jane Doe', 'Johnny Doe']
concat
方法將各個項目串接到原始 Collection 陣列中,而串接的各個項目會依照數字順序重新設定索引鍵。若要保留關聯式 Collection 的索引鍵,請參照 merge 方法。
contains()
contains
方法可用來判斷該 Collection 是否包含給定的項目。可以傳入一個閉包給 contains
方法來根據給定的真值條件測試判斷某個元素是否在該 Collection 內:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->contains(function (int $value, int $key) {4 return $value > 5;5});67// false
1$collection = collect([1, 2, 3, 4, 5]);23$collection->contains(function (int $value, int $key) {4 return $value > 5;5});67// false
或者,也可以將字串傳入 contains
方法來判斷該 Collection 是否包含給定的項目值:
1$collection = collect(['name' => 'Desk', 'price' => 100]);23$collection->contains('Desk');45// true67$collection->contains('New York');89// false
1$collection = collect(['name' => 'Desk', 'price' => 100]);23$collection->contains('Desk');45// true67$collection->contains('New York');89// false
也可以傳入一組索引鍵/值配對給 contains
方法,用來判斷給定的索引鍵/值配對是否存在於該 Collection 內:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->contains('product', 'Bookcase');78// false
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->contains('product', 'Bookcase');78// false
contains
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這標示,具有整數值的字串與一個有相同值的整數會被視為相同。請使用 containsStrict
方法來使用「嚴格 (Strict)」比對進行過濾。
請參考 doesntContain 方法以瞭解與 contains
相反的方法。
containsOneItem()
containsOneItem
用於判斷該 Collection 是否只包含一個項目:
1collect([])->containsOneItem();23// false45collect(['1'])->containsOneItem();67// true89collect(['1', '2'])->containsOneItem();1011// false
1collect([])->containsOneItem();23// false45collect(['1'])->containsOneItem();67// true89collect(['1', '2'])->containsOneItem();1011// false
containsStrict()
該方法與 contains
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
在使用 Eloquent Collection 時,該方法的行為有經過修改。
count()
count
方法回傳該 Collection 內的項目總數:
1$collection = collect([1, 2, 3, 4]);23$collection->count();45// 4
1$collection = collect([1, 2, 3, 4]);23$collection->count();45// 4
countBy()
countBy
方法會計算在該 Collection 內各個值的出現次數。預設情況下,該方法會計算所有元素的出現次數,讓你可以計算該 Collection 中特定「類型」的元素:
1$collection = collect([1, 2, 2, 2, 3]);23$counted = $collection->countBy();45$counted->all();67// [1 => 1, 2 => 3, 3 => 1]
1$collection = collect([1, 2, 2, 2, 3]);23$counted = $collection->countBy();45$counted->all();67// [1 => 1, 2 => 3, 3 => 1]
可以將一個閉包傳給 countBy
方法來依照自訂值計算所有項目:
23$counted = $collection->countBy(function (string $email) {4 return substr(strrchr($email, "@"), 1);5});67$counted->all();89// ['gmail.com' => 2, 'yahoo.com' => 1]
23$counted = $collection->countBy(function (string $email) {4 return substr(strrchr($email, "@"), 1);5});67$counted->all();89// ['gmail.com' => 2, 'yahoo.com' => 1]
crossJoin()
The crossJoin
method cross joins the collection's values among the given arrays or collections, returning a Cartesian product with all possible permutations:
1$collection = collect([1, 2]);23$matrix = $collection->crossJoin(['a', 'b']);45$matrix->all();67/*8 [9 [1, 'a'],10 [1, 'b'],11 [2, 'a'],12 [2, 'b'],13 ]14*/1516$collection = collect([1, 2]);1718$matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']);1920$matrix->all();2122/*23 [24 [1, 'a', 'I'],25 [1, 'a', 'II'],26 [1, 'b', 'I'],27 [1, 'b', 'II'],28 [2, 'a', 'I'],29 [2, 'a', 'II'],30 [2, 'b', 'I'],31 [2, 'b', 'II'],32 ]33*/
1$collection = collect([1, 2]);23$matrix = $collection->crossJoin(['a', 'b']);45$matrix->all();67/*8 [9 [1, 'a'],10 [1, 'b'],11 [2, 'a'],12 [2, 'b'],13 ]14*/1516$collection = collect([1, 2]);1718$matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']);1920$matrix->all();2122/*23 [24 [1, 'a', 'I'],25 [1, 'a', 'II'],26 [1, 'b', 'I'],27 [1, 'b', 'II'],28 [2, 'a', 'I'],29 [2, 'a', 'II'],30 [2, 'b', 'I'],31 [2, 'b', 'II'],32 ]33*/
dd()
dd
方法會傾印該 Collection 的項目,並結束目前的指令碼執行:
1$collection = collect(['John Doe', 'Jane Doe']);23$collection->dd();45/*6 Collection {7 #items: array:2 [8 0 => "John Doe"9 1 => "Jane Doe"10 ]11 }12*/
1$collection = collect(['John Doe', 'Jane Doe']);23$collection->dd();45/*6 Collection {7 #items: array:2 [8 0 => "John Doe"9 1 => "Jane Doe"10 ]11 }12*/
若不想結束目前的指令碼執行,請改為使用 dump
方法。
diff()
diff
方法會將該 Collection 的值與另一個 Collection 或純 PHP array
陣列進行比對。該方法會回傳在原始 Collection 中有出現,但給定的 Collection 中未出現的值:
1$collection = collect([1, 2, 3, 4, 5]);23$diff = $collection->diff([2, 4, 6, 8]);45$diff->all();67// [1, 3, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$diff = $collection->diff([2, 4, 6, 8]);45$diff->all();67// [1, 3, 5]
在使用 Eloquent Collection 時,該方法的行為有經過修改。
diffAssoc()
diffAssoc
方法會將該 Collection 的索引鍵/值與另一個 Collection 或純 PHP array
陣列進行比對。該方法會回傳在原始 Collection 中有出現,但給定的 Collection 中未出現的索引鍵/值配對:
1$collection = collect([2 'color' => 'orange',3 'type' => 'fruit',4 'remain' => 6,5]);67$diff = $collection->diffAssoc([8 'color' => 'yellow',9 'type' => 'fruit',10 'remain' => 3,11 'used' => 6,12]);1314$diff->all();1516// ['color' => 'orange', 'remain' => 6]
1$collection = collect([2 'color' => 'orange',3 'type' => 'fruit',4 'remain' => 6,5]);67$diff = $collection->diffAssoc([8 'color' => 'yellow',9 'type' => 'fruit',10 'remain' => 3,11 'used' => 6,12]);1314$diff->all();1516// ['color' => 'orange', 'remain' => 6]
diffKeys()
diffKey
方法會將該 Collection 的索引鍵與另一個 Collection 或純 PHP array
陣列進行比對。該方法會回傳在原始 Collection 中有出現,但給定的 Collection 中未出現的索引對:
1$collection = collect([2 'one' => 10,3 'two' => 20,4 'three' => 30,5 'four' => 40,6 'five' => 50,7]);89$diff = $collection->diffKeys([10 'two' => 2,11 'four' => 4,12 'six' => 6,13 'eight' => 8,14]);1516$diff->all();1718// ['one' => 10, 'three' => 30, 'five' => 50]
1$collection = collect([2 'one' => 10,3 'two' => 20,4 'three' => 30,5 'four' => 40,6 'five' => 50,7]);89$diff = $collection->diffKeys([10 'two' => 2,11 'four' => 4,12 'six' => 6,13 'eight' => 8,14]);1516$diff->all();1718// ['one' => 10, 'three' => 30, 'five' => 50]
doesntContain()
doesntContain
方法可用來判斷該 Collection 是否不包含給定的項目。可以傳入一個閉包給 doesntContain
方法來根據給定的真值條件測試判斷某個元素是否不在該 Collection 內:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->doesntContain(function (int $value, int $key) {4 return $value < 5;5});67// false
1$collection = collect([1, 2, 3, 4, 5]);23$collection->doesntContain(function (int $value, int $key) {4 return $value < 5;5});67// false
或者,也可以將字串傳入 doesntContain
方法來判斷該 Collection 是否不包含給定的項目值:
1$collection = collect(['name' => 'Desk', 'price' => 100]);23$collection->doesntContain('Table');45// true67$collection->doesntContain('Desk');89// false
1$collection = collect(['name' => 'Desk', 'price' => 100]);23$collection->doesntContain('Table');45// true67$collection->doesntContain('Desk');89// false
也可以傳入一組索引鍵/值配對給 doesntContains
方法,用來判斷給定的索引鍵/值配對是否不存在於該 Collection 內:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->doesntContain('product', 'Bookcase');78// true
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->doesntContain('product', 'Bookcase');78// true
doesntContain
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這表示,具有整數值的字串與一個有相同值的整數會被視為相同。
dump()
dump
方法會傾印出該 Collection 中的項目:
1$collection = collect(['John Doe', 'Jane Doe']);23$collection->dump();45/*6 Collection {7 #items: array:2 [8 0 => "John Doe"9 1 => "Jane Doe"10 ]11 }12*/
1$collection = collect(['John Doe', 'Jane Doe']);23$collection->dump();45/*6 Collection {7 #items: array:2 [8 0 => "John Doe"9 1 => "Jane Doe"10 ]11 }12*/
若想在傾印該 Collection 後停止執行指令碼,請使用 dd
方法來代替。
duplicates()
duplicates
方法會取得並回傳該 Collection 中重複的值:
1$collection = collect(['a', 'b', 'a', 'c', 'b']);23$collection->duplicates();45// [2 => 'a', 4 => 'b']
1$collection = collect(['a', 'b', 'a', 'c', 'b']);23$collection->duplicates();45// [2 => 'a', 4 => 'b']
若該 Collection 內包含陣列或物件,則可以傳入想用來檢查重複值的屬性索引鍵:
1$employees = collect([5]);67$employees->duplicates('position');89// [2 => 'Developer']
1$employees = collect([5]);67$employees->duplicates('position');89// [2 => 'Developer']
duplicatesStrict()
該方法與 duplicates
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
each()
each
方法會迭代 Collection 中的項目,並將各個項目傳給閉包:
1$collection = collect([1, 2, 3, 4]);23$collection->each(function (int $item, int $key) {4 // ...5});
1$collection = collect([1, 2, 3, 4]);23$collection->each(function (int $item, int $key) {4 // ...5});
若想停止迭代項目,可以在閉包內回傳 false
:
1$collection->each(function (int $item, int $key) {2 if (/* 條件 */) {3 return false;4 }5});
1$collection->each(function (int $item, int $key) {2 if (/* 條件 */) {3 return false;4 }5});
eachSpread()
eachSpread
方法會迭代該 Collection 的項目,並將每個巢狀項目傳入給定的回呼:
1$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);23$collection->eachSpread(function (string $name, int $age) {4 // ...5});
1$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);23$collection->eachSpread(function (string $name, int $age) {4 // ...5});
可以通過在回呼內回傳 false
來停止迭代項目:
1$collection->eachSpread(function (string $name, int $age) {2 return false;3});
1$collection->eachSpread(function (string $name, int $age) {2 return false;3});
every()
every
方法可以用來認證某個 Collection 中的所有元素是否都通過了給定的布林測試:
1collect([1, 2, 3, 4])->every(function (int $value, int $key) {2 return $value > 2;3});45// false
1collect([1, 2, 3, 4])->every(function (int $value, int $key) {2 return $value > 2;3});45// false
若 Collection 為空,則 every
方法總是回傳 true:
1$collection = collect([]);23$collection->every(function (int $value, int $key) {4 return $value > 2;5});67// true
1$collection = collect([]);23$collection->every(function (int $value, int $key) {4 return $value > 2;5});67// true
except()
except
方法會回傳該 Collection 中,除了具有特定索引鍵外的所有項目:
1$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);23$filtered = $collection->except(['price', 'discount']);45$filtered->all();67// ['product_id' => 1]
1$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);23$filtered = $collection->except(['price', 'discount']);45$filtered->all();67// ['product_id' => 1]
請參考 only 方法以瞭解與 except
相反的方法。
在使用 Eloquent Collection 時,該方法的行為有經過修改。
filter()
filter
方法會使用給定的回呼來篩選該 Collection,並只保留通過給定布林測試的項目:
1$collection = collect([1, 2, 3, 4]);23$filtered = $collection->filter(function (int $value, int $key) {4 return $value > 2;5});67$filtered->all();89// [3, 4]
1$collection = collect([1, 2, 3, 4]);23$filtered = $collection->filter(function (int $value, int $key) {4 return $value > 2;5});67$filtered->all();89// [3, 4]
若未提供回呼,則該 Collection 中所有等價於 false
的項目都會被移除:
1$collection = collect([1, 2, 3, null, false, '', 0, []]);23$collection->filter()->all();45// [1, 2, 3]
1$collection = collect([1, 2, 3, null, false, '', 0, []]);23$collection->filter()->all();45// [1, 2, 3]
請參考 reject 方法以瞭解與 filter
相反的方法。
first()
first
方法會回傳該 Collection 中通過給定布林測試的第一個元素:
1collect([1, 2, 3, 4])->first(function (int $value, int $key) {2 return $value > 2;3});45// 3
1collect([1, 2, 3, 4])->first(function (int $value, int $key) {2 return $value > 2;3});45// 3
呼叫 first
方法時也可以不給任何引數,以取得該 Collection 中的第一個元素。若該 Collection 為空,則會回傳 null
:
1collect([1, 2, 3, 4])->first();23// 1
1collect([1, 2, 3, 4])->first();23// 1
firstOrFail()
firstOrFail
方法與 first
方法完全相同。不過,若無結果,則會擲回 Illuminate\Support\ItemNotFoundException
Exception:
1collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {2 return $value > 5;3});45// 回擲 (Throw) ItemNotFoundException...
1collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {2 return $value > 5;3});45// 回擲 (Throw) ItemNotFoundException...
我們也可以不帶任何參數地呼叫 firstOrFail
方法,以取得該 Collection 中的第一個元素。若該 Collection 為空,則會擲回 Illuminate\Support\ItemNotFoundException
Exception:
1collect([])->firstOrFail();23// 擲回 ItemNotFoundException...
1collect([])->firstOrFail();23// 擲回 ItemNotFoundException...
firstWhere()
firstWhere
方法會回傳該 Collection 中具有給定索引鍵/值配對的第一個元素:
1$collection = collect([2 ['name' => 'Regena', 'age' => null],3 ['name' => 'Linda', 'age' => 14],4 ['name' => 'Diego', 'age' => 23],5 ['name' => 'Linda', 'age' => 84],6]);78$collection->firstWhere('name', 'Linda');910// ['name' => 'Linda', 'age' => 14]
1$collection = collect([2 ['name' => 'Regena', 'age' => null],3 ['name' => 'Linda', 'age' => 14],4 ['name' => 'Diego', 'age' => 23],5 ['name' => 'Linda', 'age' => 84],6]);78$collection->firstWhere('name', 'Linda');910// ['name' => 'Linda', 'age' => 14]
也可以使用比較運算子來呼叫 firstWhere
方法:
1$collection->firstWhere('age', '>=', 18);23// ['name' => 'Diego', 'age' => 23]
1$collection->firstWhere('age', '>=', 18);23// ['name' => 'Diego', 'age' => 23]
與 where 方法類似,可以傳入一個引數給 firstWhere
方法。在這種情境下,firstWhere
方法會回傳給定項目的索引鍵值可被視為「True」的第一個項目:
1$collection->firstWhere('age');23// ['name' => 'Linda', 'age' => 14]
1$collection->firstWhere('age');23// ['name' => 'Linda', 'age' => 14]
flatMap()
flatMap
方法會迭代該 Collection,並將每個值傳入給定的閉包。該閉包可自由修改項目並進行回傳,藉此依據修改的項目來建立一個新的 Collection。接著,陣列會被扁平化一個階層:
1$collection = collect([2 ['name' => 'Sally'],3 ['school' => 'Arkansas'],4 ['age' => 28]5]);67$flattened = $collection->flatMap(function (array $values) {8 return array_map('strtoupper', $values);9});1011$flattened->all();1213// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
1$collection = collect([2 ['name' => 'Sally'],3 ['school' => 'Arkansas'],4 ['age' => 28]5]);67$flattened = $collection->flatMap(function (array $values) {8 return array_map('strtoupper', $values);9});1011$flattened->all();1213// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
flatten()
flatten
方法會將一個多維 Collection 扁平化為單一維度:
1$collection = collect([2 'name' => 'taylor',3 'languages' => [4 'php', 'javascript'5 ]6]);78$flattened = $collection->flatten();910$flattened->all();1112// ['taylor', 'php', 'javascript'];
1$collection = collect([2 'name' => 'taylor',3 'languages' => [4 'php', 'javascript'5 ]6]);78$flattened = $collection->flatten();910$flattened->all();1112// ['taylor', 'php', 'javascript'];
若有需要,可以傳入一個可選的「depth 深度」引數:
1$collection = collect([2 'Apple' => [3 [4 'name' => 'iPhone 6S',5 'brand' => 'Apple'6 ],7 ],8 'Samsung' => [9 [10 'name' => 'Galaxy S7',11 'brand' => 'Samsung'12 ],13 ],14]);1516$products = $collection->flatten(1);1718$products->values()->all();1920/*21 [22 ['name' => 'iPhone 6S', 'brand' => 'Apple'],23 ['name' => 'Galaxy S7', 'brand' => 'Samsung'],24 ]25*/
1$collection = collect([2 'Apple' => [3 [4 'name' => 'iPhone 6S',5 'brand' => 'Apple'6 ],7 ],8 'Samsung' => [9 [10 'name' => 'Galaxy S7',11 'brand' => 'Samsung'12 ],13 ],14]);1516$products = $collection->flatten(1);1718$products->values()->all();1920/*21 [22 ['name' => 'iPhone 6S', 'brand' => 'Apple'],23 ['name' => 'Galaxy S7', 'brand' => 'Samsung'],24 ]25*/
在此範例中,在不提供深度的情況下呼叫 flatten
會連巢狀陣列也一併被扁平化,產生 ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']
。若提供了深度,則可指定哪些等級的巢狀陣列要被扁平化。
flip()
flip
方法會將該 Collection 的索引鍵與其對應的值進行呼喚:
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$flipped = $collection->flip();45$flipped->all();67// ['taylor' => 'name', 'laravel' => 'framework']
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$flipped = $collection->flip();45$flipped->all();67// ['taylor' => 'name', 'laravel' => 'framework']
forget()
forget
方法根據項目的索引鍵來在該 Collection 中移除項目:
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$collection->forget('name');45$collection->all();67// ['framework' => 'laravel']
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$collection->forget('name');45$collection->all();67// ['framework' => 'laravel']
與其他大多數 Collection 方法不同,forget
不會回傳經過修改的新 Collection。該方法會修改被呼叫的那個 Collection。
forPage()
forPage
會回傳一個新的 Collection,包含指定頁碼上的項目。該方法接受第一個引數為頁碼,而第二個引數則為每頁要顯示幾個項目:
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);23$chunk = $collection->forPage(2, 3);45$chunk->all();67// [4, 5, 6]
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);23$chunk = $collection->forPage(2, 3);45$chunk->all();67// [4, 5, 6]
get()
get
方法會回傳給定索引鍵上的項目。若該索引鍵不存在,則會回傳 null
:
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$value = $collection->get('name');45// taylor
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$value = $collection->get('name');45// taylor
也可以傳入可選的第二個引數提供預設值:
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$value = $collection->get('age', 34);45// 34
1$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);23$value = $collection->get('age', 34);45// 34
也可以傳入一個回呼來作為該方法的預設值。若特定的索引鍵不存在,就會回傳該回呼的結果:
1$collection->get('email', function () {3});4
1$collection->get('email', function () {3});4
groupBy()
groupBy
方法會依照給定的索引鍵來將該 Collection 的項目分組:
1$collection = collect([2 ['account_id' => 'account-x10', 'product' => 'Chair'],3 ['account_id' => 'account-x10', 'product' => 'Bookcase'],4 ['account_id' => 'account-x11', 'product' => 'Desk'],5]);67$grouped = $collection->groupBy('account_id');89$grouped->all();1011/*12 [13 'account-x10' => [14 ['account_id' => 'account-x10', 'product' => 'Chair'],15 ['account_id' => 'account-x10', 'product' => 'Bookcase'],16 ],17 'account-x11' => [18 ['account_id' => 'account-x11', 'product' => 'Desk'],19 ],20 ]21*/
1$collection = collect([2 ['account_id' => 'account-x10', 'product' => 'Chair'],3 ['account_id' => 'account-x10', 'product' => 'Bookcase'],4 ['account_id' => 'account-x11', 'product' => 'Desk'],5]);67$grouped = $collection->groupBy('account_id');89$grouped->all();1011/*12 [13 'account-x10' => [14 ['account_id' => 'account-x10', 'product' => 'Chair'],15 ['account_id' => 'account-x10', 'product' => 'Bookcase'],16 ],17 'account-x11' => [18 ['account_id' => 'account-x11', 'product' => 'Desk'],19 ],20 ]21*/
除了傳入字串 key
以外,也可以傳入一個回呼。該回呼應回傳用於分組的索引鍵值:
1$grouped = $collection->groupBy(function (array $item, int $key) {2 return substr($item['account_id'], -3);3});45$grouped->all();67/*8 [9 'x10' => [10 ['account_id' => 'account-x10', 'product' => 'Chair'],11 ['account_id' => 'account-x10', 'product' => 'Bookcase'],12 ],13 'x11' => [14 ['account_id' => 'account-x11', 'product' => 'Desk'],15 ],16 ]17*/
1$grouped = $collection->groupBy(function (array $item, int $key) {2 return substr($item['account_id'], -3);3});45$grouped->all();67/*8 [9 'x10' => [10 ['account_id' => 'account-x10', 'product' => 'Chair'],11 ['account_id' => 'account-x10', 'product' => 'Bookcase'],12 ],13 'x11' => [14 ['account_id' => 'account-x11', 'product' => 'Desk'],15 ],16 ]17*/
若有多個分組的方法,則可傳入陣列。陣列中的各個元素會被在對應的多維陣列上的層級:
1$data = new Collection([2 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],3 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],4 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],5 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],6]);78$result = $data->groupBy(['skill', function (array $item) {9 return $item['roles'];10}], preserveKeys: true);1112/*13[14 1 => [15 'Role_1' => [16 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],17 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],18 ],19 'Role_2' => [20 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],21 ],22 'Role_3' => [23 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],24 ],25 ],26 2 => [27 'Role_1' => [28 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],29 ],30 'Role_2' => [31 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],32 ],33 ],34];35*/
1$data = new Collection([2 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],3 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],4 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],5 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],6]);78$result = $data->groupBy(['skill', function (array $item) {9 return $item['roles'];10}], preserveKeys: true);1112/*13[14 1 => [15 'Role_1' => [16 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],17 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],18 ],19 'Role_2' => [20 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],21 ],22 'Role_3' => [23 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],24 ],25 ],26 2 => [27 'Role_1' => [28 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],29 ],30 'Role_2' => [31 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],32 ],33 ],34];35*/
has()
has
方法用於判斷給定的索引鍵是否存在於該 Collection 上:
1$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);23$collection->has('product');45// true67$collection->has(['product', 'amount']);89// true1011$collection->has(['amount', 'price']);1213// false
1$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);23$collection->has('product');45// true67$collection->has(['product', 'amount']);89// true1011$collection->has(['amount', 'price']);1213// false
hasAny()
hasAny
方法用於判斷給定的多個索引鍵中,是否有任何索引鍵存在於該 Collection 上:
1$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);23$collection->hasAny(['product', 'price']);45// true67$collection->hasAny(['name', 'price']);89// false
1$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);23$collection->hasAny(['product', 'price']);45// true67$collection->hasAny(['name', 'price']);89// false
implode()
implode
方法可將 Collection 內多個項目串聯。該方法的引數會依照該 Collection 中項目的類型而有所不同。若該 Collection 中包含陣列或物件,則應傳入欲串聯的屬性之索引鍵,以及要用來串聯各個值的「Glue (黏著)」字串:
1$collection = collect([2 ['account_id' => 1, 'product' => 'Desk'],3 ['account_id' => 2, 'product' => 'Chair'],4]);56$collection->implode('product', ', ');78// Desk, Chair
1$collection = collect([2 ['account_id' => 1, 'product' => 'Desk'],3 ['account_id' => 2, 'product' => 'Chair'],4]);56$collection->implode('product', ', ');78// Desk, Chair
若該 Collection 中只包含了單純的字串或數字值,則只需要傳入「Glue (黏著)」字串作為該方法唯一的引數即可:
1collect([1, 2, 3, 4, 5])->implode('-');23// '1-2-3-4-5'
1collect([1, 2, 3, 4, 5])->implode('-');23// '1-2-3-4-5'
若想為 implode 後的值自定格式,可以傳入一個閉包給 implode
方法:
1$collection->implode(function (array $item, int $key) {2 return strtoupper($item['product']);3}, ', ');45// DESK, CHAIR
1$collection->implode(function (array $item, int $key) {2 return strtoupper($item['product']);3}, ', ');45// DESK, CHAIR
intersect()
intersect
方法會從原始 Collection 中移除給定 array
或 Collection 中不存在的值。產生的 Collection 會保有原始 Collection 的索引鍵:
1$collection = collect(['Desk', 'Sofa', 'Chair']);23$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);45$intersect->all();67// [0 => 'Desk', 2 => 'Chair']
1$collection = collect(['Desk', 'Sofa', 'Chair']);23$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);45$intersect->all();67// [0 => 'Desk', 2 => 'Chair']
在使用 Eloquent Collection 時,該方法的行為有經過修改。
intersectByKeys()
intersectByKeys
方法會自原始 Collection 中移除其索引鍵不存在於給定 array
或 Collection 中的索引鍵與值:
1$collection = collect([2 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,3]);45$intersect = $collection->intersectByKeys([6 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,7]);89$intersect->all();1011// ['type' => 'screen', 'year' => 2009]
1$collection = collect([2 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,3]);45$intersect = $collection->intersectByKeys([6 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,7]);89$intersect->all();1011// ['type' => 'screen', 'year' => 2009]
isEmpty()
isEmpty
會在該 Collection 為空時回傳 true
。否則會回傳 false
:
1collect([])->isEmpty();23// true
1collect([])->isEmpty();23// true
isNotEmpty()
isNotEmpty
會在該 Collection 不為空時回傳 true
。否則會回傳 false
:
1collect([])->isNotEmpty();23// false
1collect([])->isNotEmpty();23// false
join()
join
方法會將該 Collection 中的值合併為一個字串。使用該方法的第二個引數可用來指定最後一個元素要如何被加進字串裡:
1collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'2collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'3collect(['a', 'b'])->join(', ', ' and '); // 'a and b'4collect(['a'])->join(', ', ' and '); // 'a'5collect([])->join(', ', ' and '); // ''
1collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'2collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'3collect(['a', 'b'])->join(', ', ' and '); // 'a and b'4collect(['a'])->join(', ', ' and '); // 'a'5collect([])->join(', ', ' and '); // ''
keyBy()
keyBy
方法依照給定的索引鍵來將該 Collection 加上索引鍵。若多個項目有相同的索引鍵,則新的 Collection 中只會包含最後一個項目:
1$collection = collect([2 ['product_id' => 'prod-100', 'name' => 'Desk'],3 ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$keyed = $collection->keyBy('product_id');78$keyed->all();910/*11 [12 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],13 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],14 ]15*/
1$collection = collect([2 ['product_id' => 'prod-100', 'name' => 'Desk'],3 ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$keyed = $collection->keyBy('product_id');78$keyed->all();910/*11 [12 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],13 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],14 ]15*/
也可以傳入回呼給該方法。該回呼應回傳用於為該 Collection 加上索引鍵的值:
1$keyed = $collection->keyBy(function (array $item, int $key) {2 return strtoupper($item['product_id']);3});45$keyed->all();67/*8 [9 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],10 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],11 ]12*/
1$keyed = $collection->keyBy(function (array $item, int $key) {2 return strtoupper($item['product_id']);3});45$keyed->all();67/*8 [9 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],10 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],11 ]12*/
keys()
keys
方法回傳該 Collection 中的所有索引鍵:
1$collection = collect([2 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],3 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$keys = $collection->keys();78$keys->all();910// ['prod-100', 'prod-200']
1$collection = collect([2 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],3 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$keys = $collection->keys();78$keys->all();910// ['prod-100', 'prod-200']
last()
last
方法會回傳該 Collection 中通過給定布林測試的最後一個元素:
1collect([1, 2, 3, 4])->last(function (int $value, int $key) {2 return $value < 3;3});45// 2
1collect([1, 2, 3, 4])->last(function (int $value, int $key) {2 return $value < 3;3});45// 2
呼叫 last
方法時也可以不給任何引數,以取得該 Collection 中的最後一個元素。若該 Collection 為空,則會回傳 null
:
1collect([1, 2, 3, 4])->last();23// 4
1collect([1, 2, 3, 4])->last();23// 4
lazy()
lazy
方法使用底層項目陣列來回傳一個新的 LazyCollection
實體:
1$lazyCollection = collect([1, 2, 3, 4])->lazy();23get_class($lazyCollection);45// Illuminate\Support\LazyCollection67$lazyCollection->all();89// [1, 2, 3, 4]
1$lazyCollection = collect([1, 2, 3, 4])->lazy();23get_class($lazyCollection);45// Illuminate\Support\LazyCollection67$lazyCollection->all();89// [1, 2, 3, 4]
若想轉換一個有許多項目的大型 Collection
,就特別適合使用該方法:
1$count = $hugeCollection2 ->lazy()3 ->where('country', 'FR')4 ->where('balance', '>', '100')5 ->count();
1$count = $hugeCollection2 ->lazy()3 ->where('country', 'FR')4 ->where('balance', '>', '100')5 ->count();
將 Collection 轉為 LazyCollection
後,就可避免使用到大量額外的記憶體。雖然,原始陣列的值 還是會保存在記憶體中,但之後所進行的篩選結果將不會被保存在記憶體中。因此,在篩選 Collection 結果時,將不會使用到額外的記憶體。
macro()
靜態 macro
方法可用來在執行階段將方法加入 Collection
類別內。更多資訊請參考有關擴充 Collection 的說明文件。
make()
The static make
method creates a new collection instance. See the Creating Collections section.
map()
map
方法會迭代該 Collection,並將每個值傳入給定的回呼。該回呼可自由修改項目並進行回傳,藉此依據修改的項目來建立一個新的 Collection:
1$collection = collect([1, 2, 3, 4, 5]);23$multiplied = $collection->map(function (int $item, int $key) {4 return $item * 2;5});67$multiplied->all();89// [2, 4, 6, 8, 10]
1$collection = collect([1, 2, 3, 4, 5]);23$multiplied = $collection->map(function (int $item, int $key) {4 return $item * 2;5});67$multiplied->all();89// [2, 4, 6, 8, 10]
與其他 Collection 方法類似,map
會回傳一個新的 Collection 實體。該方法不會修改正在呼叫的 Collection。若想改變原始 Collection,請使用 transform
方法代替。
mapInto()
The mapInto()
method iterates over the collection, creating a new instance of the given class by passing the value into the constructor:
1class Currency2{3 /**4 * Create a new currency instance.5 */6 function __construct(7 public string $code8 ) {}9}1011$collection = collect(['USD', 'EUR', 'GBP']);1213$currencies = $collection->mapInto(Currency::class);1415$currencies->all();1617// [Currency('USD'), Currency('EUR'), Currency('GBP')]
1class Currency2{3 /**4 * Create a new currency instance.5 */6 function __construct(7 public string $code8 ) {}9}1011$collection = collect(['USD', 'EUR', 'GBP']);1213$currencies = $collection->mapInto(Currency::class);1415$currencies->all();1617// [Currency('USD'), Currency('EUR'), Currency('GBP')]
mapSpread()
mapSpread
方法會迭代該 Collection 的項目,並將各個巢狀項目傳入給定的閉包內。該閉包可修改這些項目並回傳,藉此以修改過的項目來建立新的 Collection:
1$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);23$chunks = $collection->chunk(2);45$sequence = $chunks->mapSpread(function (int $even, int $odd) {6 return $even + $odd;7});89$sequence->all();1011// [1, 5, 9, 13, 17]
1$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);23$chunks = $collection->chunk(2);45$sequence = $chunks->mapSpread(function (int $even, int $odd) {6 return $even + $odd;7});89$sequence->all();1011// [1, 5, 9, 13, 17]
mapToGroups()
mapToGroups
方法使用給定的閉包來分組該 Collection 的項目。該閉包應回傳一個包含單一索引鍵/值配對的關聯性陣列,藉此以經過分組的值來建立新的 Collection:
1$collection = collect([2 [3 'name' => 'John Doe',4 'department' => 'Sales',5 ],6 [7 'name' => 'Jane Doe',8 'department' => 'Sales',9 ],10 [11 'name' => 'Johnny Doe',12 'department' => 'Marketing',13 ]14]);1516$grouped = $collection->mapToGroups(function (array $item, int $key) {17 return [$item['department'] => $item['name']];18});1920$grouped->all();2122/*23 [24 'Sales' => ['John Doe', 'Jane Doe'],25 'Marketing' => ['Johnny Doe'],26 ]27*/2829$grouped->get('Sales')->all();3031// ['John Doe', 'Jane Doe']
1$collection = collect([2 [3 'name' => 'John Doe',4 'department' => 'Sales',5 ],6 [7 'name' => 'Jane Doe',8 'department' => 'Sales',9 ],10 [11 'name' => 'Johnny Doe',12 'department' => 'Marketing',13 ]14]);1516$grouped = $collection->mapToGroups(function (array $item, int $key) {17 return [$item['department'] => $item['name']];18});1920$grouped->all();2122/*23 [24 'Sales' => ['John Doe', 'Jane Doe'],25 'Marketing' => ['Johnny Doe'],26 ]27*/2829$grouped->get('Sales')->all();3031// ['John Doe', 'Jane Doe']
mapWithKeys()
mapWithKeys
方法會迭代該 Collection,並將各個值傳入給定的回呼。該回呼應回傳一個包含單一索引鍵/值配對的關聯性陣列:
1$collection = collect([2 [3 'name' => 'John',4 'department' => 'Sales',6 ],7 [8 'name' => 'Jane',9 'department' => 'Marketing',11 ]12]);1314$keyed = $collection->mapWithKeys(function (array $item, int $key) {15 return [$item['email'] => $item['name']];16});1718$keyed->all();1920/*21 [22 '[email protected]' => 'John',23 '[email protected]' => 'Jane',24 ]25*/
1$collection = collect([2 [3 'name' => 'John',4 'department' => 'Sales',6 ],7 [8 'name' => 'Jane',9 'department' => 'Marketing',11 ]12]);1314$keyed = $collection->mapWithKeys(function (array $item, int $key) {15 return [$item['email'] => $item['name']];16});1718$keyed->all();1920/*21 [22 '[email protected]' => 'John',23 '[email protected]' => 'Jane',24 ]25*/
max()
max
方法回傳給定索引鍵的最大值:
1$max = collect([2 ['foo' => 10],3 ['foo' => 20]4])->max('foo');56// 2078$max = collect([1, 2, 3, 4, 5])->max();910// 5
1$max = collect([2 ['foo' => 10],3 ['foo' => 20]4])->max('foo');56// 2078$max = collect([1, 2, 3, 4, 5])->max();910// 5
median()
medium
方法會回傳給定索引鍵的中位數:
1$median = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->median('foo');78// 15910$median = collect([1, 1, 2, 4])->median();1112// 1.5
1$median = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->median('foo');78// 15910$median = collect([1, 1, 2, 4])->median();1112// 1.5
merge()
merge
方法會將給定的陣列或 Collection 與原始 Collection 合併。若在給定項目中有字串索引鍵與原始 Collection 中的字串索引鍵相同,則給定項目的值會覆蓋原始 Collection 中的值:
1$collection = collect(['product_id' => 1, 'price' => 100]);23$merged = $collection->merge(['price' => 200, 'discount' => false]);45$merged->all();67// ['product_id' => 1, 'price' => 200, 'discount' => false]
1$collection = collect(['product_id' => 1, 'price' => 100]);23$merged = $collection->merge(['price' => 200, 'discount' => false]);45$merged->all();67// ['product_id' => 1, 'price' => 200, 'discount' => false]
若給定項目的索引鍵是數字值,則其值會被加到該 Collection 的最後面:
1$collection = collect(['Desk', 'Chair']);23$merged = $collection->merge(['Bookcase', 'Door']);45$merged->all();67// ['Desk', 'Chair', 'Bookcase', 'Door']
1$collection = collect(['Desk', 'Chair']);23$merged = $collection->merge(['Bookcase', 'Door']);45$merged->all();67// ['Desk', 'Chair', 'Bookcase', 'Door']
mergeRecursive()
mergeRecursive
方法會將給定的陣列或 Collection 與原始 Collection 遞迴合併。若在給定項目中有字串索引鍵與原始 Collection 中的字串索引鍵相同,則這些索引鍵的值將被一起合併為一個陣列,且此一過程將遞迴進行:
1$collection = collect(['product_id' => 1, 'price' => 100]);23$merged = $collection->mergeRecursive([4 'product_id' => 2,5 'price' => 200,6 'discount' => false7]);89$merged->all();1011// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
1$collection = collect(['product_id' => 1, 'price' => 100]);23$merged = $collection->mergeRecursive([4 'product_id' => 2,5 'price' => 200,6 'discount' => false7]);89$merged->all();1011// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
min()
min
方法回傳給定索引鍵的最小值:
1$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');23// 1045$min = collect([1, 2, 3, 4, 5])->min();67// 1
1$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');23// 1045$min = collect([1, 2, 3, 4, 5])->min();67// 1
mode()
mode
方法會回傳給定索引鍵的眾數:
1$mode = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->mode('foo');78// [10]910$mode = collect([1, 1, 2, 4])->mode();1112// [1]1314$mode = collect([1, 1, 2, 2])->mode();1516// [1, 2]
1$mode = collect([2 ['foo' => 10],3 ['foo' => 10],4 ['foo' => 20],5 ['foo' => 40]6])->mode('foo');78// [10]910$mode = collect([1, 1, 2, 4])->mode();1112// [1]1314$mode = collect([1, 1, 2, 2])->mode();1516// [1, 2]
nth()
nth
方法會使用每 n 個元素來建立新的 Collection:
1$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);23$collection->nth(4);45// ['a', 'e']
1$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);23$collection->nth(4);45// ['a', 'e']
也可以傳入可選的第二個引數來設定起始偏移值:
1$collection->nth(4, 1);23// ['b', 'f']
1$collection->nth(4, 1);23// ['b', 'f']
only()
only
方法會回傳該 Collection 中具有特定索引鍵的所有項目:
1$collection = collect([2 'product_id' => 1,3 'name' => 'Desk',4 'price' => 100,5 'discount' => false6]);78$filtered = $collection->only(['product_id', 'name']);910$filtered->all();1112// ['product_id' => 1, 'name' => 'Desk']
1$collection = collect([2 'product_id' => 1,3 'name' => 'Desk',4 'price' => 100,5 'discount' => false6]);78$filtered = $collection->only(['product_id', 'name']);910$filtered->all();1112// ['product_id' => 1, 'name' => 'Desk']
請參考 except 方法以瞭解與 only
相反的方法。
在使用 Eloquent Collection 時,該方法的行為有經過修改。
pad()
pad
方法會以給定的值來填充陣列,直到該陣列達到特定大小。該方法的行為與 array_pad PHP 方法類似。
若要向左填充,則可指定負數大小。若給定大小的絕對值小於或等於該陣列的長度,則不會進行填充:
1$collection = collect(['A', 'B', 'C']);23$filtered = $collection->pad(5, 0);45$filtered->all();67// ['A', 'B', 'C', 0, 0]89$filtered = $collection->pad(-5, 0);1011$filtered->all();1213// [0, 0, 'A', 'B', 'C']
1$collection = collect(['A', 'B', 'C']);23$filtered = $collection->pad(5, 0);45$filtered->all();67// ['A', 'B', 'C', 0, 0]89$filtered = $collection->pad(-5, 0);1011$filtered->all();1213// [0, 0, 'A', 'B', 'C']
partition()
partition
方法可用來與 PHP 的陣列結構函式一起使用,以區分出符合與不符合給定布林測試的元素:
1$collection = collect([1, 2, 3, 4, 5, 6]);23[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {4 return $i < 3;5});67$underThree->all();89// [1, 2]1011$equalOrAboveThree->all();1213// [3, 4, 5, 6]
1$collection = collect([1, 2, 3, 4, 5, 6]);23[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {4 return $i < 3;5});67$underThree->all();89// [1, 2]1011$equalOrAboveThree->all();1213// [3, 4, 5, 6]
pipe()
pipe
方法會將該 Collection 傳入給定閉包,並回傳執行該閉包的結果:
1$collection = collect([1, 2, 3]);23$piped = $collection->pipe(function (Collection $collection) {4 return $collection->sum();5});67// 6
1$collection = collect([1, 2, 3]);23$piped = $collection->pipe(function (Collection $collection) {4 return $collection->sum();5});67// 6
pipeInto()
pipeInto
方法會以給定的類別建立新實體,並將該 Collection 傳入其建構函式內:
1class ResourceCollection2{3 /**4 * Create a new ResourceCollection instance.5 */6 public function __construct(7 public Collection $collection,8 ) {}9}1011$collection = collect([1, 2, 3]);1213$resource = $collection->pipeInto(ResourceCollection::class);1415$resource->collection->all();1617// [1, 2, 3]
1class ResourceCollection2{3 /**4 * Create a new ResourceCollection instance.5 */6 public function __construct(7 public Collection $collection,8 ) {}9}1011$collection = collect([1, 2, 3]);1213$resource = $collection->pipeInto(ResourceCollection::class);1415$resource->collection->all();1617// [1, 2, 3]
pipeThrough()
pipeThrough
方法會將該 Collection 傳入給定之包含閉包的陣列,並回傳這些閉包的執行結果:
1use Illuminate\Support\Collection;23$collection = collect([1, 2, 3]);45$result = $collection->pipeThrough([6 function (Collection $collection) {7 return $collection->merge([4, 5]);8 },9 function (Collection $collection) {10 return $collection->sum();11 },12]);1314// 15
1use Illuminate\Support\Collection;23$collection = collect([1, 2, 3]);45$result = $collection->pipeThrough([6 function (Collection $collection) {7 return $collection->merge([4, 5]);8 },9 function (Collection $collection) {10 return $collection->sum();11 },12]);1314// 15
pluck()
pluck
方法可取得給定索引鍵內的所有值:
1$collection = collect([2 ['product_id' => 'prod-100', 'name' => 'Desk'],3 ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$plucked = $collection->pluck('name');78$plucked->all();910// ['Desk', 'Chair']
1$collection = collect([2 ['product_id' => 'prod-100', 'name' => 'Desk'],3 ['product_id' => 'prod-200', 'name' => 'Chair'],4]);56$plucked = $collection->pluck('name');78$plucked->all();910// ['Desk', 'Chair']
也可以指定產生的 Collection 要如何設定索引鍵:
1$plucked = $collection->pluck('name', 'product_id');23$plucked->all();45// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
1$plucked = $collection->pluck('name', 'product_id');23$plucked->all();45// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
pluck
方法也支援使用「點 (.)」標記法來取得巢狀數值:
1$collection = collect([2 [3 'name' => 'Laracon',4 'speakers' => [5 'first_day' => ['Rosa', 'Judith'],6 ],7 ],8 [9 'name' => 'VueConf',10 'speakers' => [11 'first_day' => ['Abigail', 'Joey'],12 ],13 ],14]);1516$plucked = $collection->pluck('speakers.first_day');1718$plucked->all();1920// [['Rosa', 'Judith'], ['Abigail', 'Joey']]
1$collection = collect([2 [3 'name' => 'Laracon',4 'speakers' => [5 'first_day' => ['Rosa', 'Judith'],6 ],7 ],8 [9 'name' => 'VueConf',10 'speakers' => [11 'first_day' => ['Abigail', 'Joey'],12 ],13 ],14]);1516$plucked = $collection->pluck('speakers.first_day');1718$plucked->all();1920// [['Rosa', 'Judith'], ['Abigail', 'Joey']]
若存在重複的索引鍵,則最後一個相符合的元素會被插入 pluck 後的 Collection:
1$collection = collect([2 ['brand' => 'Tesla', 'color' => 'red'],3 ['brand' => 'Pagani', 'color' => 'white'],4 ['brand' => 'Tesla', 'color' => 'black'],5 ['brand' => 'Pagani', 'color' => 'orange'],6]);78$plucked = $collection->pluck('color', 'brand');910$plucked->all();1112// ['Tesla' => 'black', 'Pagani' => 'orange']
1$collection = collect([2 ['brand' => 'Tesla', 'color' => 'red'],3 ['brand' => 'Pagani', 'color' => 'white'],4 ['brand' => 'Tesla', 'color' => 'black'],5 ['brand' => 'Pagani', 'color' => 'orange'],6]);78$plucked = $collection->pluck('color', 'brand');910$plucked->all();1112// ['Tesla' => 'black', 'Pagani' => 'orange']
pop()
pop
方法會從該 Collection 中移除最後一個項目並將其回傳:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->pop();45// 567$collection->all();89// [1, 2, 3, 4]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->pop();45// 567$collection->all();89// [1, 2, 3, 4]
可以將整數傳入 pop
方法以從 Collection 的結尾移除並回傳多個項目:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->pop(3);45// collect([5, 4, 3])67$collection->all();89// [1, 2]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->pop(3);45// collect([5, 4, 3])67$collection->all();89// [1, 2]
prepend()
prepend
方法會將項目加至該 Collection 的開頭:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->prepend(0);45$collection->all();67// [0, 1, 2, 3, 4, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->prepend(0);45$collection->all();67// [0, 1, 2, 3, 4, 5]
也可以傳入第二個引數來指定要被加到前面之項目的索引鍵:
1$collection = collect(['one' => 1, 'two' => 2]);23$collection->prepend(0, 'zero');45$collection->all();67// ['zero' => 0, 'one' => 1, 'two' => 2]
1$collection = collect(['one' => 1, 'two' => 2]);23$collection->prepend(0, 'zero');45$collection->all();67// ['zero' => 0, 'one' => 1, 'two' => 2]
pull()
pull
方法根據項目的索引鍵來在該 Collection 中移除項目並將其回傳:
1$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);23$collection->pull('name');45// 'Desk'67$collection->all();89// ['product_id' => 'prod-100']
1$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);23$collection->pull('name');45// 'Desk'67$collection->all();89// ['product_id' => 'prod-100']
push()
push
方法會將項目加至該 Collection 的結尾:
1$collection = collect([1, 2, 3, 4]);23$collection->push(5);45$collection->all();67// [1, 2, 3, 4, 5]
1$collection = collect([1, 2, 3, 4]);23$collection->push(5);45$collection->all();67// [1, 2, 3, 4, 5]
put()
put
方法將給定的索引鍵與值設定至該 Collection 內:
1$collection = collect(['product_id' => 1, 'name' => 'Desk']);23$collection->put('price', 100);45$collection->all();67// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
1$collection = collect(['product_id' => 1, 'name' => 'Desk']);23$collection->put('price', 100);45$collection->all();67// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random()
random
方法會從該 Collection 內回傳一個隨機的項目:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->random();45// 4 - (隨機取得)
1$collection = collect([1, 2, 3, 4, 5]);23$collection->random();45// 4 - (隨機取得)
也可以傳入一個整數給 random
來指定要隨機取得幾個項目。當有明顯傳入要取得記得項目的時候,將總是回傳一個包含項目的 Collection:
1$random = $collection->random(3);23$random->all();45// [2, 4, 5] - (retrieved randomly)
1$random = $collection->random(3);23$random->all();45// [2, 4, 5] - (retrieved randomly)
若該 Collection 實體內的項目比所要求的還要少,則 random
方法會擲回一個 InvalidArgumentException
。
random
函式也接受傳入一個閉包,該閉包會收到目前 Collection 的實體:
1use Illuminate\Support\Collection;23$random = $collection->random(fn (Collection $items) => min(10, count($items)));45$random->all();67// [1, 2, 3, 4, 5] - (隨機取得)
1use Illuminate\Support\Collection;23$random = $collection->random(fn (Collection $items) => min(10, count($items)));45$random->all();67// [1, 2, 3, 4, 5] - (隨機取得)
range()
range
方法回傳一個包含了介於指定範圍內整數的 Collection:
1$collection = collect()->range(3, 6);23$collection->all();45// [3, 4, 5, 6]
1$collection = collect()->range(3, 6);23$collection->all();45// [3, 4, 5, 6]
reduce()
reduce
方法會將該 Collection 歸約 (Reduce) 為單一值,將各個迭代的結果傳送至接下來的迭代中:
1$collection = collect([1, 2, 3]);23$total = $collection->reduce(function (int $carry, int $item) {4 return $carry + $item;5});67// 6
1$collection = collect([1, 2, 3]);23$total = $collection->reduce(function (int $carry, int $item) {4 return $carry + $item;5});67// 6
第一次迭代時,$carry
的值為 null
。不過,也可以通過將第二個引數傳給 reduce
來指定初始值:
1$collection->reduce(function (int $carry, int $item) {2 return $carry + $item;3}, 4);45// 10
1$collection->reduce(function (int $carry, int $item) {2 return $carry + $item;3}, 4);45// 10
reduce
方法也會將關聯式 Collection 的索引鍵傳入給定的回呼中:
1$collection = collect([2 'usd' => 1400,3 'gbp' => 1200,4 'eur' => 1000,5]);67$ratio = [8 'usd' => 1,9 'gbp' => 1.37,10 'eur' => 1.22,11];1213$collection->reduce(function (int $carry, int $value, int $key) use ($ratio) {14 return $carry + ($value * $ratio[$key]);15});1617// 4264
1$collection = collect([2 'usd' => 1400,3 'gbp' => 1200,4 'eur' => 1000,5]);67$ratio = [8 'usd' => 1,9 'gbp' => 1.37,10 'eur' => 1.22,11];1213$collection->reduce(function (int $carry, int $value, int $key) use ($ratio) {14 return $carry + ($value * $ratio[$key]);15});1617// 4264
reduceSpread()
reduceSpread
方法會將該 Collection 歸約 (Reduce) 為一組包含值的陣列,並將每次迭代的結果傳遞給下一個迭代。這個方法與 reduce
方法類似,不過 reduceSpread
接受多個初始值:
1[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')2 ->get()3 ->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {4 if ($creditsRemaining >= $image->creditsRequired()) {5 $batch->push($image);67 $creditsRemaining -= $image->creditsRequired();8 }910 return [$creditsRemaining, $batch];11 }, $creditsAvailable, collect());
1[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')2 ->get()3 ->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {4 if ($creditsRemaining >= $image->creditsRequired()) {5 $batch->push($image);67 $creditsRemaining -= $image->creditsRequired();8 }910 return [$creditsRemaining, $batch];11 }, $creditsAvailable, collect());
reject()
reject
方法會使用給定的閉包來過濾該 Collection。若某項目應自產生的 Collection 內移除,則該閉包應回傳 true
:
1$collection = collect([1, 2, 3, 4]);23$filtered = $collection->reject(function (int $value, int $key) {4 return $value > 2;5});67$filtered->all();89// [1, 2]
1$collection = collect([1, 2, 3, 4]);23$filtered = $collection->reject(function (int $value, int $key) {4 return $value > 2;5});67$filtered->all();89// [1, 2]
有關與 reject
相反的方法。請參考 [filter
](#method-filter) 方法。
replace()
replace
方法與 merge
方法類似。不過,除了複寫有字串索引鍵的相符項目外,replace
還會複寫該 Collection 中符合數字索引鍵的項目:
1$collection = collect(['Taylor', 'Abigail', 'James']);23$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);45$replaced->all();67// ['Taylor', 'Victoria', 'James', 'Finn']
1$collection = collect(['Taylor', 'Abigail', 'James']);23$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);45$replaced->all();67// ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive()
該方法與 replace
類似,但這個方法會遞迴僅各個陣列,並將相同的取代過程套用至內部的數值:
1$collection = collect([2 'Taylor',3 'Abigail',4 [5 'James',6 'Victoria',7 'Finn'8 ]9]);1011$replaced = $collection->replaceRecursive([12 'Charlie',13 2 => [1 => 'King']14]);1516$replaced->all();1718// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
1$collection = collect([2 'Taylor',3 'Abigail',4 [5 'James',6 'Victoria',7 'Finn'8 ]9]);1011$replaced = $collection->replaceRecursive([12 'Charlie',13 2 => [1 => 'King']14]);1516$replaced->all();1718// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
reverse()
reverse
方法會將該 Collection 項目的順序顛倒過來,但保留原來的索引鍵:
1$collection = collect(['a', 'b', 'c', 'd', 'e']);23$reversed = $collection->reverse();45$reversed->all();67/*8 [9 4 => 'e',10 3 => 'd',11 2 => 'c',12 1 => 'b',13 0 => 'a',14 ]15*/
1$collection = collect(['a', 'b', 'c', 'd', 'e']);23$reversed = $collection->reverse();45$reversed->all();67/*8 [9 4 => 'e',10 3 => 'd',11 2 => 'c',12 1 => 'b',13 0 => 'a',14 ]15*/
search()
search
方法在該 Collection 中搜尋給定的值,並在找到後回傳其索引鍵。若找不到該項目,則會回傳 false
:
1$collection = collect([2, 4, 6, 8]);23$collection->search(4);45// 1
1$collection = collect([2, 4, 6, 8]);23$collection->search(4);45// 1
這裡的搜尋是使用「鬆散 (Loose)」比對的,這表示,一個整數值與一個有相同值的字串會被視為相等。若要使用「嚴格 (Strict)」比對,可傳入 true
作為該方法的第二個引數:
1collect([2, 4, 6, 8])->search('4', $strict = true);23// false
1collect([2, 4, 6, 8])->search('4', $strict = true);23// false
或者,也可以提供你自己的閉包來搜尋符合給定布林測試的第一個項目:
1collect([2, 4, 6, 8])->search(function (int $item, int $key) {2 return $item > 5;3});45// 2
1collect([2, 4, 6, 8])->search(function (int $item, int $key) {2 return $item > 5;3});45// 2
shift()
shift
方法會從該 Collection 中移除第一個項目並將其回傳:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->shift();45// 167$collection->all();89// [2, 3, 4, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->shift();45// 167$collection->all();89// [2, 3, 4, 5]
可以將整數傳入 shift
方法以從 Collection 的開頭移除並回傳多個項目:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->shift(3);45// collect([1, 2, 3])67$collection->all();89// [4, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->shift(3);45// collect([1, 2, 3])67$collection->all();89// [4, 5]
shuffle()
shuffle
方法會隨機排序該 Collection 內的項目:
1$collection = collect([1, 2, 3, 4, 5]);23$shuffled = $collection->shuffle();45$shuffled->all();67// [3, 2, 5, 1, 4] - (隨機產生)
1$collection = collect([1, 2, 3, 4, 5]);23$shuffled = $collection->shuffle();45$shuffled->all();67// [3, 2, 5, 1, 4] - (隨機產生)
skip()
skip
方法會從該 Collection 的開頭移除給定數量的元素,作為一個新的陣列回傳:
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$collection = $collection->skip(4);45$collection->all();67// [5, 6, 7, 8, 9, 10]
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$collection = $collection->skip(4);45$collection->all();67// [5, 6, 7, 8, 9, 10]
skipUntil()
skipUtil
方法會一直跳過,直到給定的回呼回傳 true
。接著,會回傳該 Collection 中剩下的項目作為一個新的 Collection 實體:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipUntil(function (int $item) {4 return $item >= 3;5});67$subset->all();89// [3, 4]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipUntil(function (int $item) {4 return $item >= 3;5});67$subset->all();89// [3, 4]
也可以傳入一個簡單的值給 skipUntil
方法,來跳過直到找到指定項目之前的所有項目:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipUntil(3);45$subset->all();67// [3, 4]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipUntil(3);45$subset->all();67// [3, 4]
若找不到給定的值,或是回呼從未回傳 true
,則 skipUntil
方法會回傳一個空 Collection。
skipWhile()
skipWhile
方法會在給定的回呼回傳 true
的時候從該 Collection 中跳過項目,並回傳該 Collection 中剩餘的項目作為一個新的 Collection:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipWhile(function (int $item) {4 return $item <= 3;5});67$subset->all();89// [4]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->skipWhile(function (int $item) {4 return $item <= 3;5});67$subset->all();89// [4]
若該回呼從未回傳 true
,則 skipWhile
方法會回傳一個空 Collection。
slice()
slice
方法會回傳該 Collection 從給定索引開始的部分:
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$slice = $collection->slice(4);45$slice->all();67// [5, 6, 7, 8, 9, 10]
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$slice = $collection->slice(4);45$slice->all();67// [5, 6, 7, 8, 9, 10]
若想限制回傳部分的大小,可傳入需要的大小作為該方法的第二個引數:
1$slice = $collection->slice(4, 2);23$slice->all();45// [5, 6]
1$slice = $collection->slice(4, 2);23$slice->all();45// [5, 6]
回傳的部分預設會保留索引鍵。若不想保留原始的索引鍵,可以使用 values
方法來重新索引這些項目。
sliding()
sliding
方法會以代表「Sliding Window」的方式將該 Collection 中的項目拆分為數個片段並回傳一個新的 Collection:
1$collection = collect([1, 2, 3, 4, 5]);23$chunks = $collection->sliding(2);45$chunks->toArray();67// [[1, 2], [2, 3], [3, 4], [4, 5]]
1$collection = collect([1, 2, 3, 4, 5]);23$chunks = $collection->sliding(2);45$chunks->toArray();67// [[1, 2], [2, 3], [3, 4], [4, 5]]
這個方法特別適合與 eachSpread
方法一起使用:
1$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) {2 $current->total = $previous->total + $current->amount;3});
1$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) {2 $current->total = $previous->total + $current->amount;3});
也可以傳入第二個可選的「區間 (step)」值,用來判斷每個片段中第一個項目的距離:
1$collection = collect([1, 2, 3, 4, 5]);23$chunks = $collection->sliding(3, step: 2);45$chunks->toArray();67// [[1, 2, 3], [3, 4, 5]]
1$collection = collect([1, 2, 3, 4, 5]);23$chunks = $collection->sliding(3, step: 2);45$chunks->toArray();67// [[1, 2, 3], [3, 4, 5]]
sole()
sole
方法會回傳該 Collection 中第一個且唯一一個通過給定真值條件測試的元素:
1collect([1, 2, 3, 4])->sole(function (int $value, int $key) {2 return $value === 2;3});45// 2
1collect([1, 2, 3, 4])->sole(function (int $value, int $key) {2 return $value === 2;3});45// 2
也可以傳入一組索引鍵/值配對給 sole
方法,sole
方法會回傳該 Collection 中符合給定索引鍵/值配對的第一個且唯一一個項目:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->sole('product', 'Chair');78// ['product' => 'Chair', 'price' => 100]
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4]);56$collection->sole('product', 'Chair');78// ['product' => 'Chair', 'price' => 100]
或者,也可以在不給定引數的情況下呼叫 sole
,以在該 Collection 中只有一個元素時取得其第一個元素:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3]);45$collection->sole();67// ['product' => 'Desk', 'price' => 200]
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3]);45$collection->sole();67// ['product' => 'Desk', 'price' => 200]
若該 Collection 中沒有能被 sole
方法回傳的元素,則會擲回一個 \Illuminate\Collections\ItemNotFoundException
例外。若有多於一個能被回傳的元素,則會擲回 \Illuminate\Collections\MultipleItemsFoundException
例外。
some()
contains
方法的別名。
sort()
sort
方法可排列該 Collection。經過排列的 Collection 會保留原始的陣列索引鍵,因此,在下列範例中我們使用了 values
方法來將索引鍵重設成連續的數字索引:
1$collection = collect([5, 3, 1, 2, 4]);23$sorted = $collection->sort();45$sorted->values()->all();67// [1, 2, 3, 4, 5]
1$collection = collect([5, 3, 1, 2, 4]);23$sorted = $collection->sort();45$sorted->values()->all();67// [1, 2, 3, 4, 5]
若有進階的排序需求,可以傳入包含自訂演算法的回呼給 sort
。請參考 PHP 說明文件中的 uasort
,該函式為 Collection 的 sort
方法內部所使用。
若有需要排序包含巢狀陣列或物件的 Collection,請參考 sortBy
與 sortByDesc
方法。
sortBy()
sortBy
方法可依照給定的索引鍵來排列該 Collection。經過排列的 Collection 會保留原始的陣列索引鍵,因此,在下列範例中我們使用了 values
方法來將索引鍵重設成連續的數字索引:
1$collection = collect([2 ['name' => 'Desk', 'price' => 200],3 ['name' => 'Chair', 'price' => 100],4 ['name' => 'Bookcase', 'price' => 150],5]);67$sorted = $collection->sortBy('price');89$sorted->values()->all();1011/*12 [13 ['name' => 'Chair', 'price' => 100],14 ['name' => 'Bookcase', 'price' => 150],15 ['name' => 'Desk', 'price' => 200],16 ]17*/
1$collection = collect([2 ['name' => 'Desk', 'price' => 200],3 ['name' => 'Chair', 'price' => 100],4 ['name' => 'Bookcase', 'price' => 150],5]);67$sorted = $collection->sortBy('price');89$sorted->values()->all();1011/*12 [13 ['name' => 'Chair', 'price' => 100],14 ['name' => 'Bookcase', 'price' => 150],15 ['name' => 'Desk', 'price' => 200],16 ]17*/
sortBy
方法也接受排序旗標作為其第二引數:
1$collection = collect([2 ['title' => 'Item 1'],3 ['title' => 'Item 12'],4 ['title' => 'Item 3'],5]);67$sorted = $collection->sortBy('title', SORT_NATURAL);89$sorted->values()->all();1011/*12 [13 ['title' => 'Item 1'],14 ['title' => 'Item 3'],15 ['title' => 'Item 12'],16 ]17*/
1$collection = collect([2 ['title' => 'Item 1'],3 ['title' => 'Item 12'],4 ['title' => 'Item 3'],5]);67$sorted = $collection->sortBy('title', SORT_NATURAL);89$sorted->values()->all();1011/*12 [13 ['title' => 'Item 1'],14 ['title' => 'Item 3'],15 ['title' => 'Item 12'],16 ]17*/
此外,也可以傳入你自己的閉包來判斷該如何排序該 Collection 的值:
1$collection = collect([2 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],3 ['name' => 'Chair', 'colors' => ['Black']],4 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],5]);67$sorted = $collection->sortBy(function (array $product, int $key) {8 return count($product['colors']);9});1011$sorted->values()->all();1213/*14 [15 ['name' => 'Chair', 'colors' => ['Black']],16 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],17 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],18 ]19*/
1$collection = collect([2 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],3 ['name' => 'Chair', 'colors' => ['Black']],4 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],5]);67$sorted = $collection->sortBy(function (array $product, int $key) {8 return count($product['colors']);9});1011$sorted->values()->all();1213/*14 [15 ['name' => 'Chair', 'colors' => ['Black']],16 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],17 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],18 ]19*/
若想以多個屬性來排序 Collection,可以傳入包含排序操作的陣列給 sortBy
方法。各個排序操作應為一個陣列,該陣列由欲排序屬性以及排序順序所組成:
1$collection = collect([2 ['name' => 'Taylor Otwell', 'age' => 34],3 ['name' => 'Abigail Otwell', 'age' => 30],4 ['name' => 'Taylor Otwell', 'age' => 36],5 ['name' => 'Abigail Otwell', 'age' => 32],6]);78$sorted = $collection->sortBy([9 ['name', 'asc'],10 ['age', 'desc'],11]);1213$sorted->values()->all();1415/*16 [17 ['name' => 'Abigail Otwell', 'age' => 32],18 ['name' => 'Abigail Otwell', 'age' => 30],19 ['name' => 'Taylor Otwell', 'age' => 36],20 ['name' => 'Taylor Otwell', 'age' => 34],21 ]22*/
1$collection = collect([2 ['name' => 'Taylor Otwell', 'age' => 34],3 ['name' => 'Abigail Otwell', 'age' => 30],4 ['name' => 'Taylor Otwell', 'age' => 36],5 ['name' => 'Abigail Otwell', 'age' => 32],6]);78$sorted = $collection->sortBy([9 ['name', 'asc'],10 ['age', 'desc'],11]);1213$sorted->values()->all();1415/*16 [17 ['name' => 'Abigail Otwell', 'age' => 32],18 ['name' => 'Abigail Otwell', 'age' => 30],19 ['name' => 'Taylor Otwell', 'age' => 36],20 ['name' => 'Taylor Otwell', 'age' => 34],21 ]22*/
當以多個屬性排序 Collection 時,也可以提供閉包來定義各個排序操作:
1$collection = collect([2 ['name' => 'Taylor Otwell', 'age' => 34],3 ['name' => 'Abigail Otwell', 'age' => 30],4 ['name' => 'Taylor Otwell', 'age' => 36],5 ['name' => 'Abigail Otwell', 'age' => 32],6]);78$sorted = $collection->sortBy([9 fn (array $a, array $b) => $a['name'] <=> $b['name'],10 fn (array $a, array $b) => $b['age'] <=> $a['age'],11]);1213$sorted->values()->all();1415/*16 [17 ['name' => 'Abigail Otwell', 'age' => 32],18 ['name' => 'Abigail Otwell', 'age' => 30],19 ['name' => 'Taylor Otwell', 'age' => 36],20 ['name' => 'Taylor Otwell', 'age' => 34],21 ]22*/
1$collection = collect([2 ['name' => 'Taylor Otwell', 'age' => 34],3 ['name' => 'Abigail Otwell', 'age' => 30],4 ['name' => 'Taylor Otwell', 'age' => 36],5 ['name' => 'Abigail Otwell', 'age' => 32],6]);78$sorted = $collection->sortBy([9 fn (array $a, array $b) => $a['name'] <=> $b['name'],10 fn (array $a, array $b) => $b['age'] <=> $a['age'],11]);1213$sorted->values()->all();1415/*16 [17 ['name' => 'Abigail Otwell', 'age' => 32],18 ['name' => 'Abigail Otwell', 'age' => 30],19 ['name' => 'Taylor Otwell', 'age' => 36],20 ['name' => 'Taylor Otwell', 'age' => 34],21 ]22*/
sortByDesc()
該方法的簽章與 sortBy
方法相同,但會以相反的順序來排序該 Collection。
sortDesc()
該方法會以與 sort
方法相反的順序來排序該 Collection:
1$collection = collect([5, 3, 1, 2, 4]);23$sorted = $collection->sortDesc();45$sorted->values()->all();67// [5, 4, 3, 2, 1]
1$collection = collect([5, 3, 1, 2, 4]);23$sorted = $collection->sortDesc();45$sorted->values()->all();67// [5, 4, 3, 2, 1]
與 sort
不同,sortDesc
不接受傳入閉包。可以使用 sort
方法並使用相反的比較來代替。
sortKeys()
sortKeys
方法以底層關聯式陣列的索引鍵來排序該 Collection:
1$collection = collect([2 'id' => 22345,3 'first' => 'John',4 'last' => 'Doe',5]);67$sorted = $collection->sortKeys();89$sorted->all();1011/*12 [13 'first' => 'John',14 'id' => 22345,15 'last' => 'Doe',16 ]17*/
1$collection = collect([2 'id' => 22345,3 'first' => 'John',4 'last' => 'Doe',5]);67$sorted = $collection->sortKeys();89$sorted->all();1011/*12 [13 'first' => 'John',14 'id' => 22345,15 'last' => 'Doe',16 ]17*/
sortKeysDesc()
該方法的簽章與 sortKeys
方法相同,但會以相反的順序來排序該 Collection。
sortKeysUsing()
sortKeysUsing
方法使用給定的回呼來以底層關聯式陣列的索引鍵排序該 Collection:
1$collection = collect([2 'ID' => 22345,3 'first' => 'John',4 'last' => 'Doe',5]);67$sorted = $collection->sortKeysUsing('strnatcasecmp');89$sorted->all();1011/*12 [13 'first' => 'John',14 'ID' => 22345,15 'last' => 'Doe',16 ]17*/
1$collection = collect([2 'ID' => 22345,3 'first' => 'John',4 'last' => 'Doe',5]);67$sorted = $collection->sortKeysUsing('strnatcasecmp');89$sorted->all();1011/*12 [13 'first' => 'John',14 'ID' => 22345,15 'last' => 'Doe',16 ]17*/
該回呼必須為回傳一個小於、等於、或大於 0 之整數的比較函式。更多資訊請參考 PHP 說明文件中有關 uksort
的部分。uksort
時 sortKeysUsing
方法內部所使用的 PHP 函式。
splice()
splice
方法會自指定的索引開始移除一部分的項目並將其回傳:
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2);45$chunk->all();67// [3, 4, 5]89$collection->all();1011// [1, 2]
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2);45$chunk->all();67// [3, 4, 5]89$collection->all();1011// [1, 2]
可以傳入第二個引數來限制產生 Collection 的大小:
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2, 1);45$chunk->all();67// [3]89$collection->all();1011// [1, 2, 4, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2, 1);45$chunk->all();67// [3]89$collection->all();1011// [1, 2, 4, 5]
此外,也可以傳入一個包含用來取代自 Collection 內移除項目的新項目作為第三個引數:
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2, 1, [10, 11]);45$chunk->all();67// [3]89$collection->all();1011// [1, 2, 10, 11, 4, 5]
1$collection = collect([1, 2, 3, 4, 5]);23$chunk = $collection->splice(2, 1, [10, 11]);45$chunk->all();67// [3]89$collection->all();1011// [1, 2, 10, 11, 4, 5]
split()
split
方法會將 Collection 拆解成給定數量的群組:
1$collection = collect([1, 2, 3, 4, 5]);23$groups = $collection->split(3);45$groups->all();67// [[1, 2], [3, 4], [5]]
1$collection = collect([1, 2, 3, 4, 5]);23$groups = $collection->split(3);45$groups->all();67// [[1, 2], [3, 4], [5]]
splitIn()
splitIn
方法會將 Collection 拆解成給定數量的群組,並會在將剩餘項目填至最後一個群組前先填滿非結尾的群組:
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$groups = $collection->splitIn(3);45$groups->all();67// [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
1$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);23$groups = $collection->splitIn(3);45$groups->all();67// [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
sum()
sum
方法會回傳該 Collection 中所有項目的綜合:
1collect([1, 2, 3, 4, 5])->sum();23// 15
1collect([1, 2, 3, 4, 5])->sum();23// 15
若該 Collection 包含了巢狀陣列或物件,應傳入一個用來判斷要加總哪個值的索引鍵:
1$collection = collect([2 ['name' => 'JavaScript: The Good Parts', 'pages' => 176],3 ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],4]);56$collection->sum('pages');78// 1272
1$collection = collect([2 ['name' => 'JavaScript: The Good Parts', 'pages' => 176],3 ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],4]);56$collection->sum('pages');78// 1272
此外,也可以傳入你自己的閉包來判斷該 Collection 中的哪個值要被加總:
1$collection = collect([2 ['name' => 'Chair', 'colors' => ['Black']],3 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],4 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],5]);67$collection->sum(function (array $product) {8 return count($product['colors']);9});1011// 6
1$collection = collect([2 ['name' => 'Chair', 'colors' => ['Black']],3 ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],4 ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],5]);67$collection->sum(function (array $product) {8 return count($product['colors']);9});1011// 6
take()
take
方法會回傳包含特定數量項目的新 Collection:
1$collection = collect([0, 1, 2, 3, 4, 5]);23$chunk = $collection->take(3);45$chunk->all();67// [0, 1, 2]
1$collection = collect([0, 1, 2, 3, 4, 5]);23$chunk = $collection->take(3);45$chunk->all();67// [0, 1, 2]
也可以傳入負數整數來從該 Collection 的結尾開始取特定數量的項目:
1$collection = collect([0, 1, 2, 3, 4, 5]);23$chunk = $collection->take(-2);45$chunk->all();67// [4, 5]
1$collection = collect([0, 1, 2, 3, 4, 5]);23$chunk = $collection->take(-2);45$chunk->all();67// [4, 5]
takeUntil()
takeUntil
方法會回傳該 Collection 中的項目,直到給定的回呼回傳 true
:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeUntil(function (int $item) {4 return $item >= 3;5});67$subset->all();89// [1, 2]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeUntil(function (int $item) {4 return $item >= 3;5});67$subset->all();89// [1, 2]
也可以傳入一個簡單的值給 takeUntil
方法,來取直到找到指定項目之前的所有項目:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeUntil(3);45$subset->all();67// [1, 2]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeUntil(3);45$subset->all();67// [1, 2]
若找不到給定的值,或是回呼從未回傳 true
,則 skipUntil
方法會回傳該 Collection 中的所有項目。
takeWhile()
takeWhile
方法會回傳該 Collection 中的項目,直到給定的回呼回傳 false
:
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeWhile(function (int $item) {4 return $item < 3;5});67$subset->all();89// [1, 2]
1$collection = collect([1, 2, 3, 4]);23$subset = $collection->takeWhile(function (int $item) {4 return $item < 3;5});67$subset->all();89// [1, 2]
若回呼從未回傳 false
,則 takeWhile
方法會回傳該 Collection 中的所有項目。
tap()
tap
方法會將該 Collection 傳給給定的回呼,讓你能在特定的時間點上「竊聽 (Tap)」該 Collection,並在不影響該 Collection 本身的情況下對其中的項目做點事情。該 Collection 會接著被 tap
方法回傳:
1collect([2, 4, 3, 1, 5])2 ->sort()3 ->tap(function (Collection $collection) {4 Log::debug('排序後的值', $collection->values()->all());5 })6 ->shift();78// 1
1collect([2, 4, 3, 1, 5])2 ->sort()3 ->tap(function (Collection $collection) {4 Log::debug('排序後的值', $collection->values()->all());5 })6 ->shift();78// 1
times()
times
靜態方法會通過叫用給定的閉包特定次數來建立一個新的 Collection:
1$collection = Collection::times(10, function (int $number) {2 return $number * 9;3});45$collection->all();67// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
1$collection = Collection::times(10, function (int $number) {2 return $number * 9;3});45$collection->all();67// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
toArray()
toArray
方法將該 Collection 轉為純 PHP array
。若該 Collection 的值為 Eloquent Model,則該 Model 也會被轉為陣列:
1$collection = collect(['name' => 'Desk', 'price' => 200]);23$collection->toArray();45/*6 [7 ['name' => 'Desk', 'price' => 200],8 ]9*/
1$collection = collect(['name' => 'Desk', 'price' => 200]);23$collection->toArray();45/*6 [7 ['name' => 'Desk', 'price' => 200],8 ]9*/
toArray
也會將該 Collection 中所有 Arrayable
實作的巢狀物件轉換為陣列。若只是想取得該 Collection 底層的原始陣列,請使用 all
方法代替。
toJson()
toJson
方法將該 Collection 轉為經過 JSON 序列化的字串:
1$collection = collect(['name' => 'Desk', 'price' => 200]);23$collection->toJson();45// '{"name":"Desk", "price":200}'
1$collection = collect(['name' => 'Desk', 'price' => 200]);23$collection->toJson();45// '{"name":"Desk", "price":200}'
transform()
transform
方法迭代該 Collection,並以該 Collection 中的各個項目呼叫給定的回呼。該 Collection 中的項目將被這個回呼所回傳的值取代:
1$collection = collect([1, 2, 3, 4, 5]);23$collection->transform(function (int $item, int $key) {4 return $item * 2;5});67$collection->all();89// [2, 4, 6, 8, 10]
1$collection = collect([1, 2, 3, 4, 5]);23$collection->transform(function (int $item, int $key) {4 return $item * 2;5});67$collection->all();89// [2, 4, 6, 8, 10]
與其他 Collection 方法不同,transform
會修改該 Collection 本身。若想建立新的 Collection,請使用 map
方法代替。
undot()
undot
方法將一組使用「點 (.)」標記法的一維 Collection 展開為多維 Collection:
1$person = collect([2 'name.first_name' => 'Marie',3 'name.last_name' => 'Valentine',4 'address.line_1' => '2992 Eagle Drive',5 'address.line_2' => '',6 'address.suburb' => 'Detroit',7 'address.state' => 'MI',8 'address.postcode' => '48219'9]);1011$person = $person->undot();1213$person->toArray();1415/*16 [17 "name" => [18 "first_name" => "Marie",19 "last_name" => "Valentine",20 ],21 "address" => [22 "line_1" => "2992 Eagle Drive",23 "line_2" => "",24 "suburb" => "Detroit",25 "state" => "MI",26 "postcode" => "48219",27 ],28 ]29*/
1$person = collect([2 'name.first_name' => 'Marie',3 'name.last_name' => 'Valentine',4 'address.line_1' => '2992 Eagle Drive',5 'address.line_2' => '',6 'address.suburb' => 'Detroit',7 'address.state' => 'MI',8 'address.postcode' => '48219'9]);1011$person = $person->undot();1213$person->toArray();1415/*16 [17 "name" => [18 "first_name" => "Marie",19 "last_name" => "Valentine",20 ],21 "address" => [22 "line_1" => "2992 Eagle Drive",23 "line_2" => "",24 "suburb" => "Detroit",25 "state" => "MI",26 "postcode" => "48219",27 ],28 ]29*/
union()
union
方法將給定的陣列加至該 Collection 中。若給定的陣列包含了已存在於原始 Collection 中的索引鍵,則會優先使用原始 Collection 中的值:
1$collection = collect([1 => ['a'], 2 => ['b']]);23$union = $collection->union([3 => ['c'], 1 => ['d']]);45$union->all();67// [1 => ['a'], 2 => ['b'], 3 => ['c']]
1$collection = collect([1 => ['a'], 2 => ['b']]);23$union = $collection->union([3 => ['c'], 1 => ['d']]);45$union->all();67// [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique()
unique
方法會回傳該 Collection 中所有不重複的項目。回傳的 Collection 會保留原始的陣列索引鍵,因此,在下列範例中我們使用了 values
方法來將索引鍵重設成連續的數字索引:
1$collection = collect([1, 1, 2, 2, 3, 4, 2]);23$unique = $collection->unique();45$unique->values()->all();67// [1, 2, 3, 4]
1$collection = collect([1, 1, 2, 2, 3, 4, 2]);23$unique = $collection->unique();45$unique->values()->all();67// [1, 2, 3, 4]
在處理巢狀陣列或物件時,可以指定用來判斷是否重複的索引鍵:
1$collection = collect([2 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],3 ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],4 ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],5 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],6 ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],7]);89$unique = $collection->unique('brand');1011$unique->values()->all();1213/*14 [15 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],16 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],17 ]18*/
1$collection = collect([2 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],3 ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],4 ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],5 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],6 ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],7]);89$unique = $collection->unique('brand');1011$unique->values()->all();1213/*14 [15 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],16 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],17 ]18*/
此外,還可以傳入你自己的閉包給 unique
方法,來指定要用哪個值判斷項目是否重複:
1$unique = $collection->unique(function (array $item) {2 return $item['brand'].$item['type'];3});45$unique->values()->all();67/*8 [9 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],10 ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],11 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],12 ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],13 ]14*/
1$unique = $collection->unique(function (array $item) {2 return $item['brand'].$item['type'];3});45$unique->values()->all();67/*8 [9 ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],10 ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],11 ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],12 ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],13 ]14*/
unique
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這標示,具有整數值的字串與一個有相同值的整數會被視為相同。請使用 uniqueStrict
方法來使用「嚴格 (Strict)」比對進行過濾。
在使用 Eloquent Collection 時,該方法的行為有經過修改。
uniqueStrict()
該方法與 unique
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
unless()
unless
方法只會在傳入該方法的第一個引數取值不為 true
時執行給定的回呼:
1$collection = collect([1, 2, 3]);23$collection->unless(true, function (Collection $collection) {4 return $collection->push(4);5});67$collection->unless(false, function (Collection $collection) {8 return $collection->push(5);9});1011$collection->all();1213// [1, 2, 3, 5]
1$collection = collect([1, 2, 3]);23$collection->unless(true, function (Collection $collection) {4 return $collection->push(4);5});67$collection->unless(false, function (Collection $collection) {8 return $collection->push(5);9});1011$collection->all();1213// [1, 2, 3, 5]
可以傳入第二個回呼給 unless
方法。當第一個傳給 unless
方法的引數為 true
時,會呼叫第二個回呼:
1$collection = collect([1, 2, 3]);23$collection->unless(true, function (Collection $collection) {4 return $collection->push(4);5}, function (Collection $collection) {6 return $collection->push(5);7});89$collection->all();1011// [1, 2, 3, 5]
1$collection = collect([1, 2, 3]);23$collection->unless(true, function (Collection $collection) {4 return $collection->push(4);5}, function (Collection $collection) {6 return $collection->push(5);7});89$collection->all();1011// [1, 2, 3, 5]
請參考 when 方法以瞭解與 unless
相反的方法。
unlessEmpty()
whenNotEmpty
方法的別名。
unlessNotEmpty()
whenEmpty
方法的別名。
unwrap()
靜態 unwrap
方法會可能的情況下從給定值中取得該 Collection 的底層項目:
1Collection::unwrap(collect('John Doe'));23// ['John Doe']45Collection::unwrap(['John Doe']);67// ['John Doe']89Collection::unwrap('John Doe');1011// 'John Doe'
1Collection::unwrap(collect('John Doe'));23// ['John Doe']45Collection::unwrap(['John Doe']);67// ['John Doe']89Collection::unwrap('John Doe');1011// 'John Doe'
value()
value
方法會取得該 Collection 中的第一個元素內取得給定的值:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Speaker', 'price' => 400],4]);56$value = $collection->value('price');78// 200
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Speaker', 'price' => 400],4]);56$value = $collection->value('price');78// 200
values()
values
方法回傳將索引鍵重設為連續整數的新 Collection:
1$collection = collect([2 10 => ['product' => 'Desk', 'price' => 200],3 11 => ['product' => 'Desk', 'price' => 200],4]);56$values = $collection->values();78$values->all();910/*11 [12 0 => ['product' => 'Desk', 'price' => 200],13 1 => ['product' => 'Desk', 'price' => 200],14 ]15*/
1$collection = collect([2 10 => ['product' => 'Desk', 'price' => 200],3 11 => ['product' => 'Desk', 'price' => 200],4]);56$values = $collection->values();78$values->all();910/*11 [12 0 => ['product' => 'Desk', 'price' => 200],13 1 => ['product' => 'Desk', 'price' => 200],14 ]15*/
when()
when
方法會在傳給該方法的第一個引數取值為 true
時執行給定的回呼。Collection 實體與傳給 when
方法的第一個引數會被提供給該閉包:
1$collection = collect([1, 2, 3]);23$collection->when(true, function (Collection $collection, int $value) {4 return $collection->push(4);5});67$collection->when(false, function (Collection $collection, int $value) {8 return $collection->push(5);9});1011$collection->all();1213// [1, 2, 3, 4]
1$collection = collect([1, 2, 3]);23$collection->when(true, function (Collection $collection, int $value) {4 return $collection->push(4);5});67$collection->when(false, function (Collection $collection, int $value) {8 return $collection->push(5);9});1011$collection->all();1213// [1, 2, 3, 4]
可以傳入第二個回呼給 when
方法。當第一個傳給 when
方法的引數為 false
時,會呼叫第二個回呼:
1$collection = collect([1, 2, 3]);23$collection->when(false, function (Collection $collection, int $value) {4 return $collection->push(4);5}, function (Collection $collection) {6 return $collection->push(5);7});89$collection->all();1011// [1, 2, 3, 5]
1$collection = collect([1, 2, 3]);23$collection->when(false, function (Collection $collection, int $value) {4 return $collection->push(4);5}, function (Collection $collection) {6 return $collection->push(5);7});89$collection->all();1011// [1, 2, 3, 5]
請參考 unless
方法以瞭解與 when
相反的方法。
whenEmpty()
whenEmpty
方法會在該 Collection 為空時執行給定的回呼:
1$collection = collect(['Michael', 'Tom']);23$collection->whenEmpty(function (Collection $collection) {4 return $collection->push('Adam');5});67$collection->all();89// ['Michael', 'Tom']101112$collection = collect();1314$collection->whenEmpty(function (Collection $collection) {15 return $collection->push('Adam');16});1718$collection->all();1920// ['Adam']
1$collection = collect(['Michael', 'Tom']);23$collection->whenEmpty(function (Collection $collection) {4 return $collection->push('Adam');5});67$collection->all();89// ['Michael', 'Tom']101112$collection = collect();1314$collection->whenEmpty(function (Collection $collection) {15 return $collection->push('Adam');16});1718$collection->all();1920// ['Adam']
可以傳入第二個閉包給 whenEmpty
方法,該閉包會在該 Collection 不為空時被執行:
1$collection = collect(['Michael', 'Tom']);23$collection->whenEmpty(function (Collection $collection) {4 return $collection->push('Adam');5}, function (Collection $collection) {6 return $collection->push('Taylor');7});89$collection->all();1011// ['Michael', 'Tom', 'Taylor']
1$collection = collect(['Michael', 'Tom']);23$collection->whenEmpty(function (Collection $collection) {4 return $collection->push('Adam');5}, function (Collection $collection) {6 return $collection->push('Taylor');7});89$collection->all();1011// ['Michael', 'Tom', 'Taylor']
請參考 whenNotEmpty
方法以瞭解與 whenEmpty
相反的方法。
whenNotEmpty()
whenNotEmpty
方法會在該 Collection 不為空時執行給定的回呼:
1$collection = collect(['michael', 'tom']);23$collection->whenNotEmpty(function (Collection $collection) {4 return $collection->push('adam');5});67$collection->all();89// ['michael', 'tom', 'adam']101112$collection = collect();1314$collection->whenNotEmpty(function (Collection $collection) {15 return $collection->push('adam');16});1718$collection->all();1920// []
1$collection = collect(['michael', 'tom']);23$collection->whenNotEmpty(function (Collection $collection) {4 return $collection->push('adam');5});67$collection->all();89// ['michael', 'tom', 'adam']101112$collection = collect();1314$collection->whenNotEmpty(function (Collection $collection) {15 return $collection->push('adam');16});1718$collection->all();1920// []
可以傳入第二個閉包給 whenNotEmpty
方法,該閉包會在該 Collection 為空時被執行:
1$collection = collect();23$collection->whenNotEmpty(function (Collection $collection) {4 return $collection->push('adam');5}, function (Collection $collection) {6 return $collection->push('taylor');7});89$collection->all();1011// ['taylor']
1$collection = collect();23$collection->whenNotEmpty(function (Collection $collection) {4 return $collection->push('adam');5}, function (Collection $collection) {6 return $collection->push('taylor');7});89$collection->all();1011// ['taylor']
請參考 whenEmpty
方法以瞭解與 whenNotEmpty
相反的方法。
where()
where
方法使用給定的索引鍵/值配對來篩選該 Collection:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->where('price', 100);910$filtered->all();1112/*13 [14 ['product' => 'Chair', 'price' => 100],15 ['product' => 'Door', 'price' => 100],16 ]17*/
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->where('price', 100);910$filtered->all();1112/*13 [14 ['product' => 'Chair', 'price' => 100],15 ['product' => 'Door', 'price' => 100],16 ]17*/
where
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這標示,具有整數值的字串與一個有相同值的整數會被視為相同。請使用 whereStrict
方法來使用「嚴格 (Strict)」比對進行過濾。
也可以選擇性地傳入一個比較運算子來作為該方法的第二個參數。支援的運算子有 '===', '!==', '!=', '==', '=', '<>', '>', '<', '>=', 與 '<=':
1$collection = collect([2 ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],3 ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],4 ['name' => 'Sue', 'deleted_at' => null],5]);67$filtered = $collection->where('deleted_at', '!=', null);89$filtered->all();1011/*12 [13 ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],14 ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],15 ]16*/
1$collection = collect([2 ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],3 ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],4 ['name' => 'Sue', 'deleted_at' => null],5]);67$filtered = $collection->where('deleted_at', '!=', null);89$filtered->all();1011/*12 [13 ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],14 ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],15 ]16*/
whereStrict()
該方法與 where
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
whereBetween()
whereBetween
方法會判斷特定項目值是否介於給定範圍來篩選該 Collection:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 80],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Pencil', 'price' => 30],6 ['product' => 'Door', 'price' => 100],7]);89$filtered = $collection->whereBetween('price', [100, 200]);1011$filtered->all();1213/*14 [15 ['product' => 'Desk', 'price' => 200],16 ['product' => 'Bookcase', 'price' => 150],17 ['product' => 'Door', 'price' => 100],18 ]19*/
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 80],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Pencil', 'price' => 30],6 ['product' => 'Door', 'price' => 100],7]);89$filtered = $collection->whereBetween('price', [100, 200]);1011$filtered->all();1213/*14 [15 ['product' => 'Desk', 'price' => 200],16 ['product' => 'Bookcase', 'price' => 150],17 ['product' => 'Door', 'price' => 100],18 ]19*/
whereIn()
whereIn
方法會從該 Collection 中移除項目值不包含在給定陣列中的項目:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->whereIn('price', [150, 200]);910$filtered->all();1112/*13 [14 ['product' => 'Desk', 'price' => 200],15 ['product' => 'Bookcase', 'price' => 150],16 ]17*/
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->whereIn('price', [150, 200]);910$filtered->all();1112/*13 [14 ['product' => 'Desk', 'price' => 200],15 ['product' => 'Bookcase', 'price' => 150],16 ]17*/
whereIn
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這標示,具有整數值的字串與一個有相同值的整數會被視為相同。請使用 whereInStrict
方法來使用「嚴格 (Strict)」比對進行過濾。
whereInStrict()
該方法與 whereIn
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
whereInstanceOf()
whereInstanceOf
方法使用給定的類別型別來篩選該 Collection:
1use App\Models\User;2use App\Models\Post;34$collection = collect([5 new User,6 new User,7 new Post,8]);910$filtered = $collection->whereInstanceOf(User::class);1112$filtered->all();1314// [App\Models\User, App\Models\User]
1use App\Models\User;2use App\Models\Post;34$collection = collect([5 new User,6 new User,7 new Post,8]);910$filtered = $collection->whereInstanceOf(User::class);1112$filtered->all();1314// [App\Models\User, App\Models\User]
whereNotBetween()
whereNotBetween
方法會判斷特定項目值是否不在給定範圍來篩選該 Collection:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 80],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Pencil', 'price' => 30],6 ['product' => 'Door', 'price' => 100],7]);89$filtered = $collection->whereNotBetween('price', [100, 200]);1011$filtered->all();1213/*14 [15 ['product' => 'Chair', 'price' => 80],16 ['product' => 'Pencil', 'price' => 30],17 ]18*/
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 80],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Pencil', 'price' => 30],6 ['product' => 'Door', 'price' => 100],7]);89$filtered = $collection->whereNotBetween('price', [100, 200]);1011$filtered->all();1213/*14 [15 ['product' => 'Chair', 'price' => 80],16 ['product' => 'Pencil', 'price' => 30],17 ]18*/
whereNotIn()
whereNotIn
方法會從該 Collection 中移除項目值不在給定陣列中的項目:
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->whereNotIn('price', [150, 200]);910$filtered->all();1112/*13 [14 ['product' => 'Chair', 'price' => 100],15 ['product' => 'Door', 'price' => 100],16 ]17*/
1$collection = collect([2 ['product' => 'Desk', 'price' => 200],3 ['product' => 'Chair', 'price' => 100],4 ['product' => 'Bookcase', 'price' => 150],5 ['product' => 'Door', 'price' => 100],6]);78$filtered = $collection->whereNotIn('price', [150, 200]);910$filtered->all();1112/*13 [14 ['product' => 'Chair', 'price' => 100],15 ['product' => 'Door', 'price' => 100],16 ]17*/
whereNotIn
方法在比對項目值時使用了「鬆散 (Loose)」的比對方法。這標示,具有整數值的字串與一個有相同值的整數會被視為相同。請使用 whereNotInStrict
方法來使用「嚴格 (Strict)」比對進行過濾。
whereNotInStrict()
該方法與 whereNotIn
方法的簽章一致。不過,所有的數值比對都是使用「嚴格」比對模式。
whereNotNull()
whereNotNull
方法回傳該 Collection 中給定索引鍵不為 null
的項目:
1$collection = collect([2 ['name' => 'Desk'],3 ['name' => null],4 ['name' => 'Bookcase'],5]);67$filtered = $collection->whereNotNull('name');89$filtered->all();1011/*12 [13 ['name' => 'Desk'],14 ['name' => 'Bookcase'],15 ]16*/
1$collection = collect([2 ['name' => 'Desk'],3 ['name' => null],4 ['name' => 'Bookcase'],5]);67$filtered = $collection->whereNotNull('name');89$filtered->all();1011/*12 [13 ['name' => 'Desk'],14 ['name' => 'Bookcase'],15 ]16*/
whereNull()
whereNull
方法回傳該 Collection 中給定索引鍵為 null
的項目:
1$collection = collect([2 ['name' => 'Desk'],3 ['name' => null],4 ['name' => 'Bookcase'],5]);67$filtered = $collection->whereNull('name');89$filtered->all();1011/*12 [13 ['name' => null],14 ]15*/
1$collection = collect([2 ['name' => 'Desk'],3 ['name' => null],4 ['name' => 'Bookcase'],5]);67$filtered = $collection->whereNull('name');89$filtered->all();1011/*12 [13 ['name' => null],14 ]15*/
wrap()
靜態 wrap
方法會在可能的情況下將給定值包裝成 Collection:
1use Illuminate\Support\Collection;23$collection = Collection::wrap('John Doe');45$collection->all();67// ['John Doe']89$collection = Collection::wrap(['John Doe']);1011$collection->all();1213// ['John Doe']1415$collection = Collection::wrap(collect('John Doe'));1617$collection->all();1819// ['John Doe']
1use Illuminate\Support\Collection;23$collection = Collection::wrap('John Doe');45$collection->all();67// ['John Doe']89$collection = Collection::wrap(['John Doe']);1011$collection->all();1213// ['John Doe']1415$collection = Collection::wrap(collect('John Doe'));1617$collection->all();1819// ['John Doe']
zip()
zip
方法將給定陣列與原始 Collection 在其對應索引上合併在一起:
1$collection = collect(['Chair', 'Desk']);23$zipped = $collection->zip([100, 200]);45$zipped->all();67// [['Chair', 100], ['Desk', 200]]
1$collection = collect(['Chair', 'Desk']);23$zipped = $collection->zip([100, 200]);45$zipped->all();67// [['Chair', 100], ['Desk', 200]]
高階訊息
Collection 也提供了「高階訊息 (Higher Order Message)」的支援,在 Collection 上進行常見操作的時候可用來當作捷徑。有提供高階訊息的 Collection 方法為:average
, avg
, contains
, each
, every
, filter
, first
, flatMap
, groupBy
, keyBy
, map
, max
, min
, partition
, reject
, skipUntil
, skipWhile
, some
, sortBy
, sortByDesc
, sum
, takeUntil
, takeWhile
與 unique
。
各個高階訊息都可作為 Collection 實體上的一個動態屬性來存取。舉例來說,我們來使用 each
高階訊息,在 Collection 中的各個物件上呼叫一個方法:
1use App\Models\User;23$users = User::where('votes', '>', 500)->get();45$users->each->markAsVip();
1use App\Models\User;23$users = User::where('votes', '>', 500)->get();45$users->each->markAsVip();
類似地,我們也可以使用 sum
高階訊息來取得使用者 Collection 中的所有「votes」加總:
1$users = User::where('group', 'Development')->get();23return $users->sum->votes;
1$users = User::where('group', 'Development')->get();23return $users->sum->votes;
Lazy Collection
簡介
在開始學習有關 Laravel 的 Lazy Collection 之前,建議先花點時間熟悉 PHP Generator。
為了補強已經很強大的 Collection
類別,LazyCollection
類別使用了 PHP 的 Generator 來讓你能在不使用太多記憶體的情況下處理非常大量的資料。
舉例來說,假設你的專案需要處理一個好幾 GB 的日誌檔,但又想利用 Laravel 的 Collection 方法來解析日誌。比起一次將整個檔案讀入記憶體,使用 Lazy Collection 的話,記憶體內一次就只會保持一小部分的檔案。
1use App\Models\LogEntry;2use Illuminate\Support\LazyCollection;34LazyCollection::make(function () {5 $handle = fopen('log.txt', 'r');67 while (($line = fgets($handle)) !== false) {8 yield $line;9 }10})->chunk(4)->map(function (array $lines) {11 return LogEntry::fromLines($lines);12})->each(function (LogEntry $logEntry) {13 // 處理 Log Entry...14});
1use App\Models\LogEntry;2use Illuminate\Support\LazyCollection;34LazyCollection::make(function () {5 $handle = fopen('log.txt', 'r');67 while (($line = fgets($handle)) !== false) {8 yield $line;9 }10})->chunk(4)->map(function (array $lines) {11 return LogEntry::fromLines($lines);12})->each(function (LogEntry $logEntry) {13 // 處理 Log Entry...14});
或者,想像一下需要迭代 10,000 個 Eloquent Model。在使用傳統 Laravel Collection 時,必須要一次將 10,000 個 Eloquent Model 讀入記憶體:
1use App\Models\User;23$users = User::all()->filter(function (User $user) {4 return $user->id > 500;5});
1use App\Models\User;23$users = User::all()->filter(function (User $user) {4 return $user->id > 500;5});
不過,Query Builder 的 cursor
方法回傳了一個 LazyCollection
實體。這樣一來就能讓你在只執行單一資料庫查詢的情況下,一次只將一個 Eloquent Model 讀入記憶體。在這個例子中,filter
回呼只會在實際迭代到個別使用者的時候才會被執行,讓我們能有效降低記憶體使用:
1use App\Models\User;23$users = User::cursor()->filter(function (User $user) {4 return $user->id > 500;5});67foreach ($users as $user) {8 echo $user->id;9}
1use App\Models\User;23$users = User::cursor()->filter(function (User $user) {4 return $user->id > 500;5});67foreach ($users as $user) {8 echo $user->id;9}
建立 Lazy Collection
若要建立 Lazy Collection 實體,應傳入 PHP Generator 方法至該 Collection 的 make
方法:
1use Illuminate\Support\LazyCollection;23LazyCollection::make(function () {4 $handle = fopen('log.txt', 'r');56 while (($line = fgets($handle)) !== false) {7 yield $line;8 }9});
1use Illuminate\Support\LazyCollection;23LazyCollection::make(function () {4 $handle = fopen('log.txt', 'r');56 while (($line = fgets($handle)) !== false) {7 yield $line;8 }9});
Enumerable Contract
幾乎所有在 Collection
類別中可用的方法都可在 LazyCollection
類別上使用。這兩個類別都實作了 Illuminate\Support\Enumerable
Contract,該介面定義了下列方法:
all average avg chunk chunkWhile collapse collect combine concat contains containsStrict count countBy crossJoin dd diff diffAssoc diffKeys dump duplicates duplicatesStrict each eachSpread every except filter first firstOrFail firstWhere flatMap flatten flip forPage get groupBy has implode intersect intersectByKeys isEmpty isNotEmpty join keyBy keys last macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode nth only pad partition pipe pluck random reduce reject replace replaceRecursive reverse search shuffle skip slice sole some sort sortBy sortByDesc sortKeys sortKeysDesc split sum take tap times toArray toJson union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict wrap zip
會修改 (Mutate) Collection 的方法 (如 shift
、pop
、prepend
等) 在 LazyCollection
類別上都 不可用。
Lazy Collection 方法
除了在 Enumerable
Contract 上定義的方法外,LazyCollection
類別還包含了下列方法:
takeUntilTimeout()
takeUntilTimeout
方法會回傳一個在特定時間前枚舉出值的新 Lazy Collection。在這個時間之後,該 Collection 便會停止枚舉:
1$lazyCollection = LazyCollection::times(INF)2 ->takeUntilTimeout(now()->addMinute());34$lazyCollection->each(function (int $number) {5 dump($number);67 sleep(1);8});910// 111// 212// ...13// 5814// 59
1$lazyCollection = LazyCollection::times(INF)2 ->takeUntilTimeout(now()->addMinute());34$lazyCollection->each(function (int $number) {5 dump($number);67 sleep(1);8});910// 111// 212// ...13// 5814// 59
為了說明如何使用這個方法,請想像一下有個會使用 Cursor 將發票存入資料庫的專案。我們可以定義一個每 15 分鐘會執行的排程任務,並在該任務中只處理 14 分鐘的發票:
1use App\Models\Invoice;2use Illuminate\Support\Carbon;34Invoice::pending()->cursor()5 ->takeUntilTimeout(6 Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')7 )8 ->each(fn (Invoice $invoice) => $invoice->submit());
1use App\Models\Invoice;2use Illuminate\Support\Carbon;34Invoice::pending()->cursor()5 ->takeUntilTimeout(6 Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')7 )8 ->each(fn (Invoice $invoice) => $invoice->submit());
tapEach()
each
方法會直接為 Collection 中各個項目呼叫給定的回呼,而 tapEach
方法則只會對被從清單中取出的項目一個一個呼叫給定的回呼:
1// Nothing has been dumped so far...2$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {3 dump($value);4});56// 傾印了三個項目...7$array = $lazyCollection->take(3)->all();89// 110// 211// 3
1// Nothing has been dumped so far...2$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {3 dump($value);4});56// 傾印了三個項目...7$array = $lazyCollection->take(3)->all();89// 110// 211// 3
remember()
remember
方法會回傳一個新的 Lazy Collection,該 Lazy Collection 會記住任何已經被枚舉過的值,並在接下來的 Collection 枚舉時不會再取出這些值:
1// 還未執行任何查詢...2$users = User::cursor()->remember();34// 已執行查詢...5// 已從資料庫中填入了前 5 位使用者...6$users->take(5)->all();78// 從 Collection 的 Cache 中取得前 5 位使用者...9// 剩下的則從資料庫中取得並填過來...10$users->take(20)->all();
1// 還未執行任何查詢...2$users = User::cursor()->remember();34// 已執行查詢...5// 已從資料庫中填入了前 5 位使用者...6$users->take(5)->all();78// 從 Collection 的 Cache 中取得前 5 位使用者...9// 剩下的則從資料庫中取得並填過來...10$users->take(20)->all();