集合
簡介
Illuminate\Support\Collection 類別提供了一個流暢、方便的包裝器,用於處理數據陣列。例如,看看下面的程式碼。我們將使用 collect 輔助函式從陣列建立一個新的集合實例,在每個元素上執行 strtoupper 函式,然後移除所有空元素
$collection = collect(['taylor', 'abigail', null])->map(function (?string $name) { return strtoupper($name);})->reject(function (string $name) { return empty($name);});
如您所見,Collection 類別允許您鏈接其方法來執行基礎陣列的流暢映射和縮減。一般而言,集合是不可變的,這意味著每個 Collection 方法都會傳回一個全新的 Collection 實例。
建立集合
如上所述,collect 輔助函式會為給定的陣列傳回一個新的 Illuminate\Support\Collection 實例。因此,建立集合就像這樣簡單
$collection = collect([1, 2, 3]);
Eloquent 查詢的結果總是會以 Collection 實例的形式傳回。
擴展集合
集合是「可巨集化的」,這允許您在執行時向 Collection 類別新增額外的方法。Illuminate\Support\Collection 類別的 macro 方法接受一個閉包,該閉包將在呼叫您的巨集時執行。巨集閉包可以透過 $this 存取集合的其他方法,就像它是集合類別的真實方法一樣。例如,以下程式碼將 toUpper 方法新增到 Collection 類別
use Illuminate\Support\Collection;use Illuminate\Support\Str; Collection::macro('toUpper', function () { return $this->map(function (string $value) { return Str::upper($value); });}); $collection = collect(['first', 'second']); $upper = $collection->toUpper(); // ['FIRST', 'SECOND']
通常,您應該在服務提供者的 boot 方法中宣告集合巨集。
巨集引數
如果需要,您可以定義接受額外引數的巨集
use Illuminate\Support\Collection;use Illuminate\Support\Facades\Lang; Collection::macro('toLocale', function (string $locale) { return $this->map(function (string $value) use ($locale) { return Lang::get($value, [], $locale); });}); $collection = collect(['first', 'second']); $translated = $collection->toLocale('es');
可用的方法
在剩餘的大部分集合文件中,我們將討論 Collection 類別上可用的每個方法。請記住,所有這些方法都可以鏈接起來,以流暢地操作基礎陣列。此外,幾乎每個方法都會傳回一個新的 Collection 實例,允許您在必要時保留集合的原始副本
after all average avg before chunk chunkWhile collapse collect combine concat contains containsOneItem containsStrict count countBy crossJoin dd diff diffAssoc diffAssocUsing diffKeys doesntContain dot dump duplicates duplicatesStrict each eachSpread ensure every except filter first firstOrFail firstWhere flatMap flatten flip forget forPage get groupBy has hasAny implode intersect intersectAssoc intersectByKeys isEmpty isNotEmpty join keyBy keys last lazy macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode multiply nth only pad partition percentage pipe pipeInto pipeThrough pluck pop prepend pull push put random range reduce reduceSpread reject replace replaceRecursive reverse search select 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
方法列表
after()
after 方法會回傳指定項目之後的項目。如果找不到指定項目或該項目是最後一個項目,則會回傳 null。
$collection = collect([1, 2, 3, 4, 5]); $collection->after(3); // 4 $collection->after(5); // null
此方法使用「寬鬆」比較來搜尋指定項目,這表示包含整數值的字串會被視為與相同值的整數相等。若要使用「嚴格」比較,您可以將 strict 引數提供給此方法。
collect([2, 4, 6, 8])->after('4', strict: true); // null
或者,您可以提供自己的閉包來搜尋第一個通過給定真值測試的項目。
collect([2, 4, 6, 8])->after(function (int $item, int $key) { return $item > 5;}); // 8
all()
all 方法會回傳集合所代表的底層陣列。
collect([1, 2, 3])->all(); // [1, 2, 3]
average()
avg 方法的別名。
avg()
avg 方法會回傳指定鍵的平均值。
$average = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo'); // 20 $average = collect([1, 1, 2, 4])->avg(); // 2
before()
before 方法與 after 方法相反。它會回傳指定項目之前的項目。如果找不到指定項目或該項目是第一個項目,則會回傳 null。
$collection = collect([1, 2, 3, 4, 5]); $collection->before(3); // 2 $collection->before(1); // null collect([2, 4, 6, 8])->before('4', strict: true); // null collect([2, 4, 6, 8])->before(function (int $item, int $key) { return $item > 5;}); // 4
chunk()
chunk 方法會將集合分割成多個較小的、具有指定大小的集合。
$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->all(); // [[1, 2, 3, 4], [5, 6, 7]]
當使用像 Bootstrap 之類的網格系統時,此方法在 視圖中特別有用。例如,假設您有一個想要在網格中顯示的 Eloquent 模型集合。
@foreach ($products->chunk(3) as $chunk) <div class="row"> @foreach ($chunk as $product) <div class="col-xs-4">{{ $product->name }}</div> @endforeach </div>@endforeach
chunkWhile()
chunkWhile 方法會根據給定回呼的評估,將集合分割成多個較小的集合。傳遞給閉包的 $chunk 變數可以用來檢查前一個元素。
$collection = collect(str_split('AABBCCCD')); $chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) { return $value === $chunk->last();}); $chunks->all(); // [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
collapse()
collapse 方法會將陣列集合摺疊成單一的平面集合。
$collection = collect([ [1, 2, 3], [4, 5, 6], [7, 8, 9],]); $collapsed = $collection->collapse(); $collapsed->all(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
collect()
collect 方法會回傳一個新的 Collection 實例,其中包含集合中目前的項目。
$collectionA = collect([1, 2, 3]); $collectionB = $collectionA->collect(); $collectionB->all(); // [1, 2, 3]
collect 方法主要用於將惰性集合轉換為標準的 Collection 實例。
$lazyCollection = LazyCollection::make(function () { yield 1; yield 2; yield 3;}); $collection = $lazyCollection->collect(); $collection::class; // 'Illuminate\Support\Collection' $collection->all(); // [1, 2, 3]
當您有一個 Enumerable 的實例並且需要一個非惰性集合實例時,collect 方法特別有用。由於 collect() 是 Enumerable 契約的一部分,因此您可以安全地使用它來取得 Collection 實例。
combine()
combine 方法會將集合的值作為鍵,與另一個陣列或集合的值結合。
$collection = collect(['name', 'age']); $combined = $collection->combine(['George', 29]); $combined->all(); // ['name' => 'George', 'age' => 29]
concat()
concat 方法會將給定的 array 或集合的值附加到另一個集合的末端。
$collection = collect(['John Doe']); $concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']); $concatenated->all(); // ['John Doe', 'Jane Doe', 'Johnny Doe']
concat 方法會為附加到原始集合的項目重新以數字編排索引。若要在關聯式集合中保留鍵,請參閱 merge 方法。
contains()
contains 方法會判斷集合是否包含指定的項目。您可以將閉包傳遞給 contains 方法,以判斷集合中是否存在符合給定真值測試的元素。
$collection = collect([1, 2, 3, 4, 5]); $collection->contains(function (int $value, int $key) { return $value > 5;}); // false
或者,您可以將字串傳遞給 contains 方法,以判斷集合是否包含指定的項目值。
$collection = collect(['name' => 'Desk', 'price' => 100]); $collection->contains('Desk'); // true $collection->contains('New York'); // false
您也可以將鍵/值對傳遞給 contains 方法,這會判斷集合中是否存在指定的配對。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->contains('product', 'Bookcase'); // false
contains 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串會被視為與相同值的整數相等。使用 containsStrict 方法來使用「嚴格」比較篩選。
如需 contains 的反向,請參閱 doesntContain 方法。
containsOneItem()
containsOneItem 方法會判斷集合是否包含單一項目。
collect([])->containsOneItem(); // false collect(['1'])->containsOneItem(); // true collect(['1', '2'])->containsOneItem(); // false
containsStrict()
此方法與 contains 方法具有相同的簽名;但是,所有值都使用「嚴格」比較來比較。
當使用Eloquent 集合時,此方法的行為會被修改。
count()
count 方法會回傳集合中的項目總數。
$collection = collect([1, 2, 3, 4]); $collection->count(); // 4
countBy()
countBy 方法會計算集合中值的出現次數。預設情況下,此方法會計算每個元素的出現次數,讓您可以計算集合中某些「類型」的元素。
$collection = collect([1, 2, 2, 2, 3]); $counted = $collection->countBy(); $counted->all(); // [1 => 1, 2 => 3, 3 => 1]
您可以將閉包傳遞給 countBy 方法,以依自訂值計算所有項目。
$counted = $collection->countBy(function (string $email) { return substr(strrchr($email, "@"), 1);}); $counted->all(); // ['gmail.com' => 2, 'yahoo.com' => 1]
crossJoin()
crossJoin 方法會在給定的陣列或集合之間交叉聯結集合的值,並回傳具有所有可能排列方式的笛卡爾積。
$collection = collect([1, 2]); $matrix = $collection->crossJoin(['a', 'b']); $matrix->all(); /* [ [1, 'a'], [1, 'b'], [2, 'a'], [2, 'b'], ]*/ $collection = collect([1, 2]); $matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']); $matrix->all(); /* [ [1, 'a', 'I'], [1, 'a', 'II'], [1, 'b', 'I'], [1, 'b', 'II'], [2, 'a', 'I'], [2, 'a', 'II'], [2, 'b', 'I'], [2, 'b', 'II'], ]*/
dd()
dd 方法會傾印集合的項目並結束指令碼的執行。
$collection = collect(['John Doe', 'Jane Doe']); $collection->dd(); /* Collection { #items: array:2 [ 0 => "John Doe" 1 => "Jane Doe" ] }*/
如果您不想停止執行指令碼,請改用 dump 方法。
diff()
diff 方法會根據其值將集合與另一個集合或純 PHP array 進行比較。此方法會回傳原始集合中未出現在給定集合中的值。
$collection = collect([1, 2, 3, 4, 5]); $diff = $collection->diff([2, 4, 6, 8]); $diff->all(); // [1, 3, 5]
當使用Eloquent 集合時,此方法的行為會被修改。
diffAssoc()
diffAssoc 方法會根據其鍵和值將集合與另一個集合或純 PHP array 進行比較。此方法會回傳原始集合中未出現在給定集合中的鍵/值對。
$collection = collect([ 'color' => 'orange', 'type' => 'fruit', 'remain' => 6,]); $diff = $collection->diffAssoc([ 'color' => 'yellow', 'type' => 'fruit', 'remain' => 3, 'used' => 6,]); $diff->all(); // ['color' => 'orange', 'remain' => 6]
diffAssocUsing()
與 diffAssoc 不同,diffAssocUsing 接受使用者提供的回呼函數來進行索引比較。
$collection = collect([ 'color' => 'orange', 'type' => 'fruit', 'remain' => 6,]); $diff = $collection->diffAssocUsing([ 'Color' => 'yellow', 'Type' => 'fruit', 'Remain' => 3,], 'strnatcasecmp'); $diff->all(); // ['color' => 'orange', 'remain' => 6]
回呼必須是傳回小於、等於或大於零的整數的比較函數。如需更多資訊,請參閱 PHP 文件中關於 array_diff_uassoc 的說明,這是 diffAssocUsing 方法在內部使用的 PHP 函數。
diffKeys()
diffKeys 方法會根據其鍵將集合與另一個集合或純 PHP array 進行比較。此方法會回傳原始集合中未出現在給定集合中的鍵/值對。
$collection = collect([ 'one' => 10, 'two' => 20, 'three' => 30, 'four' => 40, 'five' => 50,]); $diff = $collection->diffKeys([ 'two' => 2, 'four' => 4, 'six' => 6, 'eight' => 8,]); $diff->all(); // ['one' => 10, 'three' => 30, 'five' => 50]
doesntContain()
doesntContain 方法會判斷集合是否不包含指定的項目。您可以將閉包傳遞給 doesntContain 方法,以判斷集合中是否存在不符合給定真值測試的元素。
$collection = collect([1, 2, 3, 4, 5]); $collection->doesntContain(function (int $value, int $key) { return $value < 5;}); // false
或者,您可以將字串傳遞給 doesntContain 方法,以判斷集合是否不包含指定的項目值。
$collection = collect(['name' => 'Desk', 'price' => 100]); $collection->doesntContain('Table'); // true $collection->doesntContain('Desk'); // false
您也可以將鍵/值對傳遞給 doesntContain 方法,這會判斷集合中是否存在指定的配對。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->doesntContain('product', 'Bookcase'); // true
doesntContain 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串會被視為與相同值的整數相等。
dot()
dot 方法會將多維集合扁平化為單一級別的集合,該集合使用「點」表示法來指示深度。
$collection = collect(['products' => ['desk' => ['price' => 100]]]); $flattened = $collection->dot(); $flattened->all(); // ['products.desk.price' => 100]
dump()
dump 方法會傾印集合的項目。
$collection = collect(['John Doe', 'Jane Doe']); $collection->dump(); /* Collection { #items: array:2 [ 0 => "John Doe" 1 => "Jane Doe" ] }*/
如果您想在傾印集合後停止執行指令碼,請改用 dd 方法。
duplicates()
duplicates 方法會從集合中擷取並回傳重複的值。
$collection = collect(['a', 'b', 'a', 'c', 'b']); $collection->duplicates(); // [2 => 'a', 4 => 'b']
如果集合包含陣列或物件,您可以傳遞要檢查重複值之屬性的鍵。
$employees = collect([]); $employees->duplicates('position'); // [2 => 'Developer']
duplicatesStrict()
這個方法具有與 duplicates 方法相同的簽名;但是,所有值都使用「嚴格」比較進行比較。
each()
each 方法會迭代集合中的項目,並將每個項目傳遞給一個閉包。
$collection = collect([1, 2, 3, 4]); $collection->each(function (int $item, int $key) { // ...});
如果您想停止迭代項目,可以從您的閉包返回 false。
$collection->each(function (int $item, int $key) { if (/* condition */) { return false; }});
eachSpread()
eachSpread 方法會迭代集合的項目,將每個巢狀項目值傳遞到給定的回呼函數中。
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]); $collection->eachSpread(function (string $name, int $age) { // ...});
您可以通過從回呼函數返回 false 來停止迭代項目。
$collection->eachSpread(function (string $name, int $age) { return false;});
ensure()
ensure 方法可用於驗證集合的所有元素是否為給定的類型或類型列表。否則,將拋出 UnexpectedValueException。
return $collection->ensure(User::class); return $collection->ensure([User::class, Customer::class]);
也可以指定諸如 string、int、float、bool 和 array 等基本類型。
return $collection->ensure('int');
ensure 方法不保證之後不會將不同類型的元素添加到集合中。
every()
every 方法可用於驗證集合的所有元素是否通過給定的真值測試。
collect([1, 2, 3, 4])->every(function (int $value, int $key) { return $value > 2;}); // false
如果集合為空,則 every 方法將返回 true。
$collection = collect([]); $collection->every(function (int $value, int $key) { return $value > 2;}); // true
except()
except 方法會返回集合中除指定鍵之外的所有項目。
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]); $filtered = $collection->except(['price', 'discount']); $filtered->all(); // ['product_id' => 1]
有關 except 的反向操作,請參閱 only 方法。
當使用 Eloquent 集合時,此方法的行為會被修改。
filter()
filter 方法使用給定的回呼函數過濾集合,僅保留通過給定真值測試的項目。
$collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function (int $value, int $key) { return $value > 2;}); $filtered->all(); // [3, 4]
如果沒有提供回呼函數,則會移除集合中所有等同於 false 的項目。
$collection = collect([1, 2, 3, null, false, '', 0, []]); $collection->filter()->all(); // [1, 2, 3]
有關 filter 的反向操作,請參閱 reject 方法。
first()
first 方法會返回集合中通過給定真值測試的第一個元素。
collect([1, 2, 3, 4])->first(function (int $value, int $key) { return $value > 2;}); // 3
您也可以不帶參數呼叫 first 方法,以取得集合中的第一個元素。如果集合為空,則返回 null。
collect([1, 2, 3, 4])->first(); // 1
firstOrFail()
firstOrFail 方法與 first 方法相同;但是,如果沒有找到結果,則會拋出 Illuminate\Support\ItemNotFoundException 異常。
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) { return $value > 5;}); // Throws ItemNotFoundException...
您也可以不帶參數呼叫 firstOrFail 方法,以取得集合中的第一個元素。如果集合為空,則會拋出 Illuminate\Support\ItemNotFoundException 異常。
collect([])->firstOrFail(); // Throws ItemNotFoundException...
firstWhere()
firstWhere 方法會返回集合中具有給定鍵/值配對的第一個元素。
$collection = collect([ ['name' => 'Regena', 'age' => null], ['name' => 'Linda', 'age' => 14], ['name' => 'Diego', 'age' => 23], ['name' => 'Linda', 'age' => 84],]); $collection->firstWhere('name', 'Linda'); // ['name' => 'Linda', 'age' => 14]
您也可以使用比較運算符呼叫 firstWhere 方法。
$collection->firstWhere('age', '>=', 18); // ['name' => 'Diego', 'age' => 23]
與 where 方法類似,您可以傳遞一個參數給 firstWhere 方法。在這種情況下,firstWhere 方法會返回給定項目鍵的值為「真值」的第一個項目。
$collection->firstWhere('age'); // ['name' => 'Linda', 'age' => 14]
flatMap()
flatMap 方法會迭代集合,並將每個值傳遞給給定的閉包。閉包可以自由地修改項目並返回它,從而形成一個新的修改項目集合。然後,陣列會被展平一層。
$collection = collect([ ['name' => 'Sally'], ['school' => 'Arkansas'], ['age' => 28]]); $flattened = $collection->flatMap(function (array $values) { return array_map('strtoupper', $values);}); $flattened->all(); // ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
flatten()
flatten 方法會將多維集合展平為單維集合。
$collection = collect([ 'name' => 'taylor', 'languages' => [ 'php', 'javascript' ]]); $flattened = $collection->flatten(); $flattened->all(); // ['taylor', 'php', 'javascript'];
如有必要,您可以傳遞一個「深度」參數給 flatten 方法。
$collection = collect([ 'Apple' => [ [ 'name' => 'iPhone 6S', 'brand' => 'Apple' ], ], 'Samsung' => [ [ 'name' => 'Galaxy S7', 'brand' => 'Samsung' ], ],]); $products = $collection->flatten(1); $products->values()->all(); /* [ ['name' => 'iPhone 6S', 'brand' => 'Apple'], ['name' => 'Galaxy S7', 'brand' => 'Samsung'], ]*/
在此範例中,呼叫 flatten 而不提供深度也會展平巢狀陣列,產生 ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']。提供深度可讓您指定巢狀陣列將被展平的層數。
flip()
flip 方法會交換集合的鍵及其對應的值。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $flipped = $collection->flip(); $flipped->all(); // ['taylor' => 'name', 'laravel' => 'framework']
forget()
forget 方法會依鍵從集合中移除項目。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); // Forget a single key...$collection->forget('name'); // ['framework' => 'laravel'] // Forget multiple keys...$collection->forget(['name', 'framework']); // []
與大多數其他集合方法不同,forget 不會返回新的修改後的集合;它會修改並返回它所呼叫的集合。
forPage()
forPage 方法會返回一個新的集合,其中包含給定頁碼上將顯示的項目。該方法接受頁碼作為第一個參數,並接受每頁顯示的項目數作為第二個參數。
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]); $chunk = $collection->forPage(2, 3); $chunk->all(); // [4, 5, 6]
get()
get 方法會返回給定鍵的項目。如果該鍵不存在,則返回 null。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('name'); // taylor
您可以選擇性地傳遞一個預設值作為第二個參數。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('age', 34); // 34
您甚至可以將回呼函數作為方法的預設值傳遞。如果指定的鍵不存在,則會返回回呼函數的結果。
$collection->get('email', function () {});
groupBy()
groupBy 方法會依給定鍵對集合的項目進行分組。
$collection = collect([ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ['account_id' => 'account-x11', 'product' => 'Desk'],]); $grouped = $collection->groupBy('account_id'); $grouped->all(); /* [ 'account-x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'account-x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ]*/
您可以傳遞一個回呼函數,而不是傳遞字串 key。回呼函數應返回您希望用來分組的值。
$grouped = $collection->groupBy(function (array $item, int $key) { return substr($item['account_id'], -3);}); $grouped->all(); /* [ 'x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ]*/
可以將多個分組條件作為陣列傳遞。每個陣列元素將被應用到多維陣列中的相應層級。
$data = new Collection([ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']], 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],]); $result = $data->groupBy(['skill', function (array $item) { return $item['roles'];}], preserveKeys: true); /*[ 1 => [ 'Role_1' => [ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], ], 'Role_2' => [ 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], ], 'Role_3' => [ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], ], ], 2 => [ 'Role_1' => [ 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']], ], 'Role_2' => [ 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']], ], ],];*/
has()
has 方法會判斷集合中是否存在給定的鍵。
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]); $collection->has('product'); // true $collection->has(['product', 'amount']); // true $collection->has(['amount', 'price']); // false
hasAny()
hasAny 方法會判斷集合中是否存在任何給定的鍵。
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]); $collection->hasAny(['product', 'price']); // true $collection->hasAny(['name', 'price']); // false
implode()
implode 方法會聯接集合中的項目。其參數取決於集合中項目的類型。如果集合包含陣列或物件,您應該傳遞您要聯接的屬性的鍵,以及您希望放在值之間的「膠水」字串。
$collection = collect([ ['account_id' => 1, 'product' => 'Desk'], ['account_id' => 2, 'product' => 'Chair'],]); $collection->implode('product', ', '); // Desk, Chair
如果集合包含簡單的字串或數值,則您應該將「膠水」作為方法的唯一參數傳遞。
collect([1, 2, 3, 4, 5])->implode('-'); // '1-2-3-4-5'
如果您想要格式化被聯接的值,可以傳遞一個閉包給 implode 方法。
$collection->implode(function (array $item, int $key) { return strtoupper($item['product']);}, ', '); // DESK, CHAIR
intersect()
intersect 方法會從原始集合中移除給定 array 或集合中不存在的任何值。產生的集合將保留原始集合的鍵。
$collection = collect(['Desk', 'Sofa', 'Chair']); $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); $intersect->all(); // [0 => 'Desk', 2 => 'Chair']
當使用 Eloquent 集合時,此方法的行為會被修改。
intersectAssoc()
intersectAssoc 方法會將原始集合與另一個集合或 array 進行比較,返回在所有給定集合中都存在的鍵/值對。
$collection = collect([ 'color' => 'red', 'size' => 'M', 'material' => 'cotton']); $intersect = $collection->intersectAssoc([ 'color' => 'blue', 'size' => 'M', 'material' => 'polyester']); $intersect->all(); // ['size' => 'M']
intersectByKeys()
intersectByKeys 方法會從原始集合中移除給定 array 或集合中不存在的任何鍵及其對應的值。
$collection = collect([ 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,]); $intersect = $collection->intersectByKeys([ 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,]); $intersect->all(); // ['type' => 'screen', 'year' => 2009]
isEmpty()
如果集合為空,則 isEmpty 方法會返回 true;否則,返回 false。
collect([])->isEmpty(); // true
isNotEmpty()
如果集合不為空,則 isNotEmpty 方法會返回 true;否則,返回 false。
collect([])->isNotEmpty(); // false
join()
join 方法會使用字串聯接集合的值。使用此方法的第二個參數,您還可以指定如何將最後一個元素附加到字串。
collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'collect(['a', 'b'])->join(', ', ' and '); // 'a and b'collect(['a'])->join(', ', ' and '); // 'a'collect([])->join(', ', ' and '); // ''
keyBy()
keyBy 方法會依給定鍵來設定集合的鍵。如果多個項目具有相同的鍵,則只有最後一個會出現在新的集合中。
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk'], ['product_id' => 'prod-200', 'name' => 'Chair'],]); $keyed = $collection->keyBy('product_id'); $keyed->all(); /* [ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ]*/
您也可以將回呼函數傳遞給該方法。回呼函數應返回要設定集合鍵的值。
$keyed = $collection->keyBy(function (array $item, int $key) { return strtoupper($item['product_id']);}); $keyed->all(); /* [ 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ]*/
keys()
keys 方法會返回集合的所有鍵。
$collection = collect([ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],]); $keys = $collection->keys(); $keys->all(); // ['prod-100', 'prod-200']
last()
last 方法會返回集合中通過給定真值測試的最後一個元素。
collect([1, 2, 3, 4])->last(function (int $value, int $key) { return $value < 3;}); // 2
您也可以不帶參數呼叫 last 方法,以取得集合中的最後一個元素。如果集合為空,則返回 null。
collect([1, 2, 3, 4])->last(); // 4
lazy()
lazy 方法會從底層的項目陣列返回一個新的 LazyCollection 實例。
$lazyCollection = collect([1, 2, 3, 4])->lazy(); $lazyCollection::class; // Illuminate\Support\LazyCollection $lazyCollection->all(); // [1, 2, 3, 4]
當您需要對包含許多項目的大型 Collection 執行轉換時,這尤其有用。
$count = $hugeCollection ->lazy() ->where('country', 'FR') ->where('balance', '>', '100') ->count();
通過將集合轉換為 LazyCollection,我們可以避免分配大量額外的記憶體。儘管原始集合仍然將其值保留在記憶體中,但後續的過濾器不會。因此,過濾集合的結果時實際上不會分配額外的記憶體。
macro()
靜態 macro 方法可讓您在運行時將方法添加到 Collection 類別。有關更多資訊,請參閱有關擴展集合的文件。
make()
靜態 make 方法會建立一個新的集合實例。請參閱「建立集合」章節。
map()
map 方法會迭代集合,並將每個值傳遞給給定的回呼函數。回呼函數可以自由地修改項目並返回它,從而形成一個新的修改項目集合。
$collection = collect([1, 2, 3, 4, 5]); $multiplied = $collection->map(function (int $item, int $key) { return $item * 2;}); $multiplied->all(); // [2, 4, 6, 8, 10]
與大多數其他集合方法一樣,map 會返回一個新的集合實例;它不會修改它所呼叫的集合。如果您想轉換原始集合,請使用 transform 方法。
mapInto()
mapInto() 方法會迭代集合,通過將值傳遞到建構子中來建立給定類別的新實例。
class Currency{ /** * Create a new currency instance. */ function __construct( public string $code, ) {}} $collection = collect(['USD', 'EUR', 'GBP']); $currencies = $collection->mapInto(Currency::class); $currencies->all(); // [Currency('USD'), Currency('EUR'), Currency('GBP')]
mapSpread()
mapSpread 方法會迭代集合的項目,將每個巢狀項目值傳遞到給定的閉包。閉包可以自由地修改項目並返回它,從而形成一個新的修改項目集合。
$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); $chunks = $collection->chunk(2); $sequence = $chunks->mapSpread(function (int $even, int $odd) { return $even + $odd;}); $sequence->all(); // [1, 5, 9, 13, 17]
mapToGroups()
mapToGroups 方法會依給定的閉包對集合的項目進行分組。閉包應返回一個包含單個鍵/值對的關聯陣列,從而形成一個新的分組值集合。
$collection = collect([ [ 'name' => 'John Doe', 'department' => 'Sales', ], [ 'name' => 'Jane Doe', 'department' => 'Sales', ], [ 'name' => 'Johnny Doe', 'department' => 'Marketing', ]]); $grouped = $collection->mapToGroups(function (array $item, int $key) { return [$item['department'] => $item['name']];}); $grouped->all(); /* [ 'Sales' => ['John Doe', 'Jane Doe'], 'Marketing' => ['Johnny Doe'], ]*/ $grouped->get('Sales')->all(); // ['John Doe', 'Jane Doe']
mapWithKeys()
mapWithKeys 方法會迭代集合,並將每個值傳遞給給定的回呼函數。回呼函數應返回一個包含單個鍵/值對的關聯陣列。
$collection = collect([ [ 'name' => 'John', 'department' => 'Sales', ], [ 'name' => 'Jane', 'department' => 'Marketing', ]]); $keyed = $collection->mapWithKeys(function (array $item, int $key) { return [$item['email'] => $item['name']];}); $keyed->all(); /* [ '[email protected]' => 'John', '[email protected]' => 'Jane', ]*/
max()
max 方法會返回給定鍵的最大值。
$max = collect([ ['foo' => 10], ['foo' => 20]])->max('foo'); // 20 $max = collect([1, 2, 3, 4, 5])->max(); // 5
median()
median 方法會返回給定鍵的中位數值。
$median = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo'); // 15 $median = collect([1, 1, 2, 4])->median(); // 1.5
merge()
merge 方法會將給定的陣列或集合與原始集合合併。如果給定項目中的字串鍵與原始集合中的字串鍵匹配,則給定項目的值將覆蓋原始集合中的值。
$collection = collect(['product_id' => 1, 'price' => 100]); $merged = $collection->merge(['price' => 200, 'discount' => false]); $merged->all(); // ['product_id' => 1, 'price' => 200, 'discount' => false]
如果給定項目的鍵為數字,則這些值將附加到集合的末尾
$collection = collect(['Desk', 'Chair']); $merged = $collection->merge(['Bookcase', 'Door']); $merged->all(); // ['Desk', 'Chair', 'Bookcase', 'Door']
mergeRecursive()
mergeRecursive 方法會將給定的陣列或集合以遞迴方式與原始集合合併。如果給定項目中的字串鍵與原始集合中的字串鍵匹配,則這些鍵的值會合併到一個陣列中,並且此操作會遞迴進行
$collection = collect(['product_id' => 1, 'price' => 100]); $merged = $collection->mergeRecursive([ 'product_id' => 2, 'price' => 200, 'discount' => false]); $merged->all(); // ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
min()
min 方法會返回給定鍵的最小值
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo'); // 10 $min = collect([1, 2, 3, 4, 5])->min(); // 1
mode()
mode 方法會返回給定鍵的眾數
$mode = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo'); // [10] $mode = collect([1, 1, 2, 4])->mode(); // [1] $mode = collect([1, 1, 2, 2])->mode(); // [1, 2]
multiply()
multiply 方法會建立集合中所有項目的指定份數副本
$users = collect([])->multiply(3); /* [ ['name' => 'User #1', 'email' => '[email protected]'], ['name' => 'User #2', 'email' => '[email protected]'], ['name' => 'User #1', 'email' => '[email protected]'], ['name' => 'User #2', 'email' => '[email protected]'], ['name' => 'User #1', 'email' => '[email protected]'], ['name' => 'User #2', 'email' => '[email protected]'], ]*/
nth()
nth 方法會建立一個新的集合,其中包含每第 n 個元素
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']); $collection->nth(4); // ['a', 'e']
您可以選擇性地將起始偏移量作為第二個參數傳遞
$collection->nth(4, 1); // ['b', 'f']
only()
only 方法會返回集合中具有指定鍵的項目
$collection = collect([ 'product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]); $filtered = $collection->only(['product_id', 'name']); $filtered->all(); // ['product_id' => 1, 'name' => 'Desk']
如需 only 的反向操作,請參閱 except 方法。
當使用 Eloquent 集合時,此方法的行為會有所修改。
pad()
pad 方法會使用給定的值填充陣列,直到陣列達到指定的大小。此方法的行為類似於 array_pad PHP 函數。
若要向左填充,您應該指定負數大小。如果給定大小的絕對值小於或等於陣列的長度,則不會進行填充
$collection = collect(['A', 'B', 'C']); $filtered = $collection->pad(5, 0); $filtered->all(); // ['A', 'B', 'C', 0, 0] $filtered = $collection->pad(-5, 0); $filtered->all(); // [0, 0, 'A', 'B', 'C']
partition()
partition 方法可以與 PHP 陣列解構結合使用,以將通過給定真值測試的元素與未通過測試的元素分開
$collection = collect([1, 2, 3, 4, 5, 6]); [$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) { return $i < 3;}); $underThree->all(); // [1, 2] $equalOrAboveThree->all(); // [3, 4, 5, 6]
percentage()
percentage 方法可用於快速判斷集合中通過給定真值測試的項目百分比
$collection = collect([1, 1, 2, 2, 2, 3]); $percentage = $collection->percentage(fn ($value) => $value === 1); // 33.33
預設情況下,百分比將四捨五入到小數點後兩位。但是,您可以透過向方法提供第二個參數來自訂此行為
$percentage = $collection->percentage(fn ($value) => $value === 1, precision: 3); // 33.333
pipe()
pipe 方法會將集合傳遞給給定的閉包,並返回執行閉包的結果
$collection = collect([1, 2, 3]); $piped = $collection->pipe(function (Collection $collection) { return $collection->sum();}); // 6
pipeInto()
pipeInto 方法會建立給定類別的新實例,並將集合傳遞給建構子
class ResourceCollection{ /** * Create a new ResourceCollection instance. */ public function __construct( public Collection $collection, ) {}} $collection = collect([1, 2, 3]); $resource = $collection->pipeInto(ResourceCollection::class); $resource->collection->all(); // [1, 2, 3]
pipeThrough()
pipeThrough 方法會將集合傳遞給給定的閉包陣列,並返回執行閉包的結果
use Illuminate\Support\Collection; $collection = collect([1, 2, 3]); $result = $collection->pipeThrough([ function (Collection $collection) { return $collection->merge([4, 5]); }, function (Collection $collection) { return $collection->sum(); },]); // 15
pluck()
pluck 方法會檢索給定鍵的所有值
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk'], ['product_id' => 'prod-200', 'name' => 'Chair'],]); $plucked = $collection->pluck('name'); $plucked->all(); // ['Desk', 'Chair']
您還可以指定希望如何為結果集合設定鍵
$plucked = $collection->pluck('name', 'product_id'); $plucked->all(); // ['prod-100' => 'Desk', 'prod-200' => 'Chair']
pluck 方法還支援使用「點」符號檢索巢狀值
$collection = collect([ [ 'name' => 'Laracon', 'speakers' => [ 'first_day' => ['Rosa', 'Judith'], ], ], [ 'name' => 'VueConf', 'speakers' => [ 'first_day' => ['Abigail', 'Joey'], ], ],]); $plucked = $collection->pluck('speakers.first_day'); $plucked->all(); // [['Rosa', 'Judith'], ['Abigail', 'Joey']]
如果存在重複的鍵,則最後一個匹配的元素將插入到選取的集合中
$collection = collect([ ['brand' => 'Tesla', 'color' => 'red'], ['brand' => 'Pagani', 'color' => 'white'], ['brand' => 'Tesla', 'color' => 'black'], ['brand' => 'Pagani', 'color' => 'orange'],]); $plucked = $collection->pluck('color', 'brand'); $plucked->all(); // ['Tesla' => 'black', 'Pagani' => 'orange']
pop()
pop 方法會移除並返回集合中的最後一個項目
$collection = collect([1, 2, 3, 4, 5]); $collection->pop(); // 5 $collection->all(); // [1, 2, 3, 4]
您可以將整數傳遞給 pop 方法,以從集合的末尾移除並返回多個項目
$collection = collect([1, 2, 3, 4, 5]); $collection->pop(3); // collect([5, 4, 3]) $collection->all(); // [1, 2]
prepend()
prepend 方法會將項目新增到集合的開頭
$collection = collect([1, 2, 3, 4, 5]); $collection->prepend(0); $collection->all(); // [0, 1, 2, 3, 4, 5]
您也可以傳遞第二個參數來指定前置項目的鍵
$collection = collect(['one' => 1, 'two' => 2]); $collection->prepend(0, 'zero'); $collection->all(); // ['zero' => 0, 'one' => 1, 'two' => 2]
pull()
pull 方法會依鍵從集合中移除並返回項目
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']); $collection->pull('name'); // 'Desk' $collection->all(); // ['product_id' => 'prod-100']
push()
push 方法會將項目附加到集合的末尾
$collection = collect([1, 2, 3, 4]); $collection->push(5); $collection->all(); // [1, 2, 3, 4, 5]
put()
put 方法會在集合中設定給定的鍵和值
$collection = collect(['product_id' => 1, 'name' => 'Desk']); $collection->put('price', 100); $collection->all(); // ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random()
random 方法會從集合中返回隨機項目
$collection = collect([1, 2, 3, 4, 5]); $collection->random(); // 4 - (retrieved randomly)
您可以將整數傳遞給 random 來指定要隨機檢索的項目數。當明確傳遞您希望接收的項目數時,始終會返回項目集合
$random = $collection->random(3); $random->all(); // [2, 4, 5] - (retrieved randomly)
如果集合實例的項目少於請求的項目數,random 方法會擲回 InvalidArgumentException。
random 方法也接受閉包,該閉包將接收目前的集合實例
use Illuminate\Support\Collection; $random = $collection->random(fn (Collection $items) => min(10, count($items))); $random->all(); // [1, 2, 3, 4, 5] - (retrieved randomly)
range()
range 方法會返回一個包含指定範圍之間整數的集合
$collection = collect()->range(3, 6); $collection->all(); // [3, 4, 5, 6]
reduce()
reduce 方法會將集合縮減為單個值,並將每次迭代的結果傳遞到後續迭代中
$collection = collect([1, 2, 3]); $total = $collection->reduce(function (?int $carry, int $item) { return $carry + $item;}); // 6
第一次迭代的 $carry 值為 null;但是,您可以透過將第二個參數傳遞給 reduce 來指定其初始值
$collection->reduce(function (int $carry, int $item) { return $carry + $item;}, 4); // 10
reduce 方法也會將關聯集合中的陣列鍵傳遞給給定的回呼
$collection = collect([ 'usd' => 1400, 'gbp' => 1200, 'eur' => 1000,]); $ratio = [ 'usd' => 1, 'gbp' => 1.37, 'eur' => 1.22,]; $collection->reduce(function (int $carry, int $value, int $key) use ($ratio) { return $carry + ($value * $ratio[$key]);}); // 4264
reduceSpread()
reduceSpread 方法會將集合縮減為一個值陣列,並將每次迭代的結果傳遞到後續迭代中。此方法與 reduce 方法類似;但是,它可以接受多個初始值
[$creditsRemaining, $batch] = Image::where('status', 'unprocessed') ->get() ->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) { if ($creditsRemaining >= $image->creditsRequired()) { $batch->push($image); $creditsRemaining -= $image->creditsRequired(); } return [$creditsRemaining, $batch]; }, $creditsAvailable, collect());
reject()
reject 方法會使用給定的閉包篩選集合。如果項目應從結果集合中移除,則閉包應返回 true
$collection = collect([1, 2, 3, 4]); $filtered = $collection->reject(function (int $value, int $key) { return $value > 2;}); $filtered->all(); // [1, 2]
如需 reject 方法的反向操作,請參閱 filter 方法。
replace()
replace 方法的行為類似於 merge;但是,除了覆寫具有字串鍵的匹配項目之外,replace 方法也會覆寫集合中具有匹配數字鍵的項目
$collection = collect(['Taylor', 'Abigail', 'James']); $replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']); $replaced->all(); // ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive()
此方法的工作方式與 replace 相同,但它會遞迴到陣列中,並將相同的取代程序套用到內部值
$collection = collect([ 'Taylor', 'Abigail', [ 'James', 'Victoria', 'Finn' ]]); $replaced = $collection->replaceRecursive([ 'Charlie', 2 => [1 => 'King']]); $replaced->all(); // ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
reverse()
reverse 方法會反轉集合項目的順序,同時保留原始鍵
$collection = collect(['a', 'b', 'c', 'd', 'e']); $reversed = $collection->reverse(); $reversed->all(); /* [ 4 => 'e', 3 => 'd', 2 => 'c', 1 => 'b', 0 => 'a', ]*/
search()
search 方法會在集合中搜尋給定的值,如果找到則返回其鍵。如果找不到項目,則返回 false
$collection = collect([2, 4, 6, 8]); $collection->search(4); // 1
搜尋是使用「寬鬆」比較完成的,這表示具有整數值的字串將被視為等於相同值的整數。若要使用「嚴格」比較,請將 true 作為方法的第二個參數傳遞
collect([2, 4, 6, 8])->search('4', strict: true); // false
或者,您可以提供自己的閉包來搜尋第一個通過給定真值測試的項目。
collect([2, 4, 6, 8])->search(function (int $item, int $key) { return $item > 5;}); // 2
select()
select 方法會從集合中選取給定的鍵,類似於 SQL SELECT 陳述式
$users = collect([ ['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'], ['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],]); $users->select(['name', 'role']); /* [ ['name' => 'Taylor Otwell', 'role' => 'Developer'], ['name' => 'Victoria Faith', 'role' => 'Researcher'], ],*/
shift()
shift 方法會移除並返回集合中的第一個項目
$collection = collect([1, 2, 3, 4, 5]); $collection->shift(); // 1 $collection->all(); // [2, 3, 4, 5]
您可以將整數傳遞給 shift 方法,以從集合的開頭移除並返回多個項目
$collection = collect([1, 2, 3, 4, 5]); $collection->shift(3); // collect([1, 2, 3]) $collection->all(); // [4, 5]
shuffle()
shuffle 方法會隨機洗牌集合中的項目
$collection = collect([1, 2, 3, 4, 5]); $shuffled = $collection->shuffle(); $shuffled->all(); // [3, 2, 5, 1, 4] - (generated randomly)
skip()
skip 方法會返回一個新的集合,其中已從集合的開頭移除給定數量的元素
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $collection = $collection->skip(4); $collection->all(); // [5, 6, 7, 8, 9, 10]
skipUntil()
當給定的回呼返回 false 時,skipUntil 方法會略過集合中的項目。一旦回呼返回 true,集合中所有剩餘的項目都將以新集合的形式返回
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipUntil(function (int $item) { return $item >= 3;}); $subset->all(); // [3, 4]
您也可以將簡單值傳遞給 skipUntil 方法,以略過所有項目,直到找到給定的值
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipUntil(3); $subset->all(); // [3, 4]
如果找不到給定的值或回呼永遠不會返回 true,則 skipUntil 方法會返回空集合。
skipWhile()
當給定的回呼返回 true 時,skipWhile 方法會略過集合中的項目。一旦回呼返回 false,集合中所有剩餘的項目都將以新集合的形式返回
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipWhile(function (int $item) { return $item <= 3;}); $subset->all(); // [4]
如果回呼永遠不會返回 false,則 skipWhile 方法會返回空集合。
slice()
slice 方法會返回從給定索引開始的集合切片
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $slice = $collection->slice(4); $slice->all(); // [5, 6, 7, 8, 9, 10]
如果您想要限制返回切片的大小,請將所需的大小作為方法的第二個參數傳遞
$slice = $collection->slice(4, 2); $slice->all(); // [5, 6]
預設情況下,返回的切片將保留鍵。如果您不希望保留原始鍵,可以使用 values 方法來重新索引它們。
sliding()
sliding 方法會返回一個新的區塊集合,代表集合中項目的「滑動視窗」視圖
$collection = collect([1, 2, 3, 4, 5]); $chunks = $collection->sliding(2); $chunks->toArray(); // [[1, 2], [2, 3], [3, 4], [4, 5]]
這在與 eachSpread 方法結合使用時特別有用
$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) { $current->total = $previous->total + $current->amount;});
您可以選擇性地傳遞第二個「步驟」值,該值決定每個區塊的第一個項目之間的距離
$collection = collect([1, 2, 3, 4, 5]); $chunks = $collection->sliding(3, step: 2); $chunks->toArray(); // [[1, 2, 3], [3, 4, 5]]
sole()
sole 方法會返回集合中通過給定真值測試的第一個元素,但前提是真值測試正好匹配一個元素
collect([1, 2, 3, 4])->sole(function (int $value, int $key) { return $value === 2;}); // 2
您也可以將鍵/值組傳遞給 sole 方法,該方法會返回集合中匹配給定組的第一個元素,但前提是正好有一個元素匹配
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->sole('product', 'Chair'); // ['product' => 'Chair', 'price' => 100]
或者,您也可以在不帶參數的情況下呼叫 sole 方法,以取得集合中的第一個元素(如果只有一個元素)
$collection = collect([ ['product' => 'Desk', 'price' => 200],]); $collection->sole(); // ['product' => 'Desk', 'price' => 200]
如果集合中沒有應該由 sole 方法返回的元素,則會擲回 \Illuminate\Collections\ItemNotFoundException 例外狀況。如果有超過一個應該返回的元素,則會擲回 \Illuminate\Collections\MultipleItemsFoundException。
some()
別名為 contains 方法。
sort()
sort 方法會排序集合。已排序的集合會保留原始陣列鍵,因此在下列範例中,我們將使用 values 方法將鍵重設為連續編號的索引
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sort(); $sorted->values()->all(); // [1, 2, 3, 4, 5]
如果您的排序需求更進階,您可以將回呼傳遞給 sort,其中包含您自己的演算法。請參閱關於 uasort 的 PHP 文件,這是集合的 sort 方法在內部使用的。
如果您需要排序巢狀陣列或物件的集合,請參閱 sortBy 和 sortByDesc 方法。
sortBy()
sortBy 方法會依給定的鍵排序集合。已排序的集合會保留原始陣列鍵,因此在下列範例中,我們將使用 values 方法將鍵重設為連續編號的索引
$collection = collect([ ['name' => 'Desk', 'price' => 200], ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150],]); $sorted = $collection->sortBy('price'); $sorted->values()->all(); /* [ ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ['name' => 'Desk', 'price' => 200], ]*/
sortBy 方法接受 排序旗標作為其第二個參數
$collection = collect([ ['title' => 'Item 1'], ['title' => 'Item 12'], ['title' => 'Item 3'],]); $sorted = $collection->sortBy('title', SORT_NATURAL); $sorted->values()->all(); /* [ ['title' => 'Item 1'], ['title' => 'Item 3'], ['title' => 'Item 12'], ]*/
或者,您可以傳遞您自己的閉包,以決定如何排序集合的值
$collection = collect([ ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],]); $sorted = $collection->sortBy(function (array $product, int $key) { return count($product['colors']);}); $sorted->values()->all(); /* [ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], ]*/
如果您想要依多個屬性排序集合,您可以將排序操作的陣列傳遞給 sortBy 方法。每個排序操作都應該是一個陣列,其中包含您想要排序的屬性以及所需排序的方向
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32],]); $sorted = $collection->sortBy([ ['name', 'asc'], ['age', 'desc'],]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ]*/
依多個屬性排序集合時,您也可以提供定義每個排序操作的閉包
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32],]); $sorted = $collection->sortBy([ fn (array $a, array $b) => $a['name'] <=> $b['name'], fn (array $a, array $b) => $b['age'] <=> $a['age'],]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ]*/
sortByDesc()
此方法與 sortBy 方法具有相同的簽名,但會以相反的順序對集合進行排序。
sortDesc()
此方法會以與 sort 方法相反的順序對集合進行排序。
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sortDesc(); $sorted->values()->all(); // [5, 4, 3, 2, 1]
與 sort 不同,您不能將閉包傳遞給 sortDesc。相反地,您應該使用 sort 方法並反轉您的比較。
sortKeys()
sortKeys 方法會依據底層關聯陣列的鍵來排序集合。
$collection = collect([ 'id' => 22345, 'first' => 'John', 'last' => 'Doe',]); $sorted = $collection->sortKeys(); $sorted->all(); /* [ 'first' => 'John', 'id' => 22345, 'last' => 'Doe', ]*/
sortKeysDesc()
此方法與 sortKeys 方法具有相同的簽名,但會以相反的順序對集合進行排序。
sortKeysUsing()
sortKeysUsing 方法會使用回呼函式,依據底層關聯陣列的鍵來排序集合。
$collection = collect([ 'ID' => 22345, 'first' => 'John', 'last' => 'Doe',]); $sorted = $collection->sortKeysUsing('strnatcasecmp'); $sorted->all(); /* [ 'first' => 'John', 'ID' => 22345, 'last' => 'Doe', ]*/
回呼函式必須是一個比較函式,它會傳回一個小於、等於或大於零的整數。如需更多資訊,請參閱 PHP 文件中有關 uksort 的說明,這是 sortKeysUsing 方法在內部使用的 PHP 函式。
splice()
splice 方法會移除並傳回從指定索引開始的項目切片。
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2); $chunk->all(); // [3, 4, 5] $collection->all(); // [1, 2]
您可以傳遞第二個參數來限制結果集合的大小。
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1); $chunk->all(); // [3] $collection->all(); // [1, 2, 4, 5]
此外,您可以傳遞第三個參數,其中包含要取代從集合中移除的項目之新項目。
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1, [10, 11]); $chunk->all(); // [3] $collection->all(); // [1, 2, 10, 11, 4, 5]
split()
split 方法會將集合分成指定的群組數量。
$collection = collect([1, 2, 3, 4, 5]); $groups = $collection->split(3); $groups->all(); // [[1, 2], [3, 4], [5]]
splitIn()
splitIn 方法會將集合分成指定的群組數量,在將剩餘項目分配到最後一個群組之前,先將非終端群組完全填滿。
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $groups = $collection->splitIn(3); $groups->all(); // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
sum()
sum 方法會傳回集合中所有項目的總和。
collect([1, 2, 3, 4, 5])->sum(); // 15
如果集合包含巢狀陣列或物件,您應該傳遞一個鍵,該鍵將用於判斷要加總的值。
$collection = collect([ ['name' => 'JavaScript: The Good Parts', 'pages' => 176], ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],]); $collection->sum('pages'); // 1272
此外,您可以傳遞自己的閉包來判斷要加總的集合值。
$collection = collect([ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],]); $collection->sum(function (array $product) { return count($product['colors']);}); // 6
take()
take 方法會傳回一個包含指定項目數的新集合。
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(3); $chunk->all(); // [0, 1, 2]
您也可以傳遞一個負整數,從集合的末端取得指定數量的項目。
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(-2); $chunk->all(); // [4, 5]
takeUntil()
takeUntil 方法會傳回集合中的項目,直到給定的回呼函式傳回 true 為止。
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeUntil(function (int $item) { return $item >= 3;}); $subset->all(); // [1, 2]
您也可以傳遞一個簡單的值給 takeUntil 方法,以取得項目,直到找到給定的值為止。
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeUntil(3); $subset->all(); // [1, 2]
如果找不到給定的值或回呼函式永遠不會傳回 true,takeUntil 方法將傳回集合中的所有項目。
takeWhile()
takeWhile 方法會傳回集合中的項目,直到給定的回呼函式傳回 false 為止。
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeWhile(function (int $item) { return $item < 3;}); $subset->all(); // [1, 2]
如果回呼函式永遠不會傳回 false,takeWhile 方法將傳回集合中的所有項目。
tap()
tap 方法會將集合傳遞給給定的回呼函式,讓您可以在特定時間點「tap」到集合,並對項目執行某些操作,而不會影響集合本身。然後 tap 方法會傳回集合。
collect([2, 4, 3, 1, 5]) ->sort() ->tap(function (Collection $collection) { Log::debug('Values after sorting', $collection->values()->all()); }) ->shift(); // 1
times()
靜態 times 方法會透過調用給定閉包指定的次數來建立一個新的集合。
$collection = Collection::times(10, function (int $number) { return $number * 9;}); $collection->all(); // [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
toArray()
toArray 方法會將集合轉換為純 PHP array。如果集合的值是 Eloquent 模型,則這些模型也會被轉換為陣列。
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toArray(); /* [ ['name' => 'Desk', 'price' => 200], ]*/
toArray 也會將集合中所有巢狀的 Arrayable 物件轉換為陣列。如果您想要取得集合的底層原始陣列,請改用 all 方法。
toJson()
toJson 方法會將集合轉換為 JSON 序列化字串。
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toJson(); // '{"name":"Desk", "price":200}'
transform()
transform 方法會迭代集合,並針對集合中的每個項目調用給定的回呼函式。集合中的項目將被回呼函式傳回的值所取代。
$collection = collect([1, 2, 3, 4, 5]); $collection->transform(function (int $item, int $key) { return $item * 2;}); $collection->all(); // [2, 4, 6, 8, 10]
與大多數其他集合方法不同,transform 會修改集合本身。如果您希望建立一個新的集合,請改用 map 方法。
undot()
undot 方法會將使用「點」表示法的單維集合展開為多維集合。
$person = collect([ 'name.first_name' => 'Marie', 'name.last_name' => 'Valentine', 'address.line_1' => '2992 Eagle Drive', 'address.line_2' => '', 'address.suburb' => 'Detroit', 'address.state' => 'MI', 'address.postcode' => '48219']); $person = $person->undot(); $person->toArray(); /* [ "name" => [ "first_name" => "Marie", "last_name" => "Valentine", ], "address" => [ "line_1" => "2992 Eagle Drive", "line_2" => "", "suburb" => "Detroit", "state" => "MI", "postcode" => "48219", ], ]*/
union()
union 方法會將給定的陣列新增至集合。如果給定的陣列包含原始集合中已有的鍵,則會優先使用原始集合的值。
$collection = collect([1 => ['a'], 2 => ['b']]); $union = $collection->union([3 => ['c'], 1 => ['d']]); $union->all(); // [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique()
unique 方法會傳回集合中所有唯一的項目。傳回的集合會保留原始陣列的鍵,因此在以下範例中,我們將使用 values 方法將鍵重設為連續編號的索引。
$collection = collect([1, 1, 2, 2, 3, 4, 2]); $unique = $collection->unique(); $unique->values()->all(); // [1, 2, 3, 4]
當處理巢狀陣列或物件時,您可以指定用於判斷唯一性的鍵。
$collection = collect([ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],]); $unique = $collection->unique('brand'); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ]*/
最後,您也可以將自己的閉包傳遞給 unique 方法,以指定哪個值應該決定項目的唯一性。
$unique = $collection->unique(function (array $item) { return $item['brand'].$item['type'];}); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], ]*/
unique 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串將被視為等於相同值的整數。使用 uniqueStrict 方法以使用「嚴格」比較進行過濾。
當使用 Eloquent 集合 時,此方法的行為會被修改。
uniqueStrict()
此方法與 unique 方法具有相同的簽名;但是,所有值都會使用「嚴格」比較進行比較。
unless()
unless 方法將執行給定的回呼函式,除非給定給該方法的第一個參數評估為 true。
$collection = collect([1, 2, 3]); $collection->unless(true, function (Collection $collection) { return $collection->push(4);}); $collection->unless(false, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
可以將第二個回呼函式傳遞給 unless 方法。當給定給 unless 方法的第一個參數評估為 true 時,將會執行第二個回呼函式。
$collection = collect([1, 2, 3]); $collection->unless(true, function (Collection $collection) { return $collection->push(4);}, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
如需 unless 的相反操作,請參閱 when 方法。
unlessEmpty()
whenNotEmpty 方法的別名。
unlessNotEmpty()
whenEmpty 方法的別名。
unwrap()
靜態 unwrap 方法會從給定的值傳回集合的底層項目(如果適用)。
Collection::unwrap(collect('John Doe')); // ['John Doe'] Collection::unwrap(['John Doe']); // ['John Doe'] Collection::unwrap('John Doe'); // 'John Doe'
value()
value 方法會從集合的第一個元素中檢索給定的值。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Speaker', 'price' => 400],]); $value = $collection->value('price'); // 200
values()
values 方法會傳回一個新的集合,其鍵會重設為連續的整數。
$collection = collect([ 10 => ['product' => 'Desk', 'price' => 200], 11 => ['product' => 'Desk', 'price' => 200],]); $values = $collection->values(); $values->all(); /* [ 0 => ['product' => 'Desk', 'price' => 200], 1 => ['product' => 'Desk', 'price' => 200], ]*/
when()
當給定給該方法的第一個參數評估為 true 時,when 方法將執行給定的回呼函式。集合實例和給定給 when 方法的第一個參數將會提供給閉包。
$collection = collect([1, 2, 3]); $collection->when(true, function (Collection $collection, int $value) { return $collection->push(4);}); $collection->when(false, function (Collection $collection, int $value) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 4]
可以將第二個回呼函式傳遞給 when 方法。當給定給 when 方法的第一個參數評估為 false 時,將會執行第二個回呼函式。
$collection = collect([1, 2, 3]); $collection->when(false, function (Collection $collection, int $value) { return $collection->push(4);}, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
如需 when 的相反操作,請參閱 unless 方法。
whenEmpty()
當集合為空時,whenEmpty 方法將執行給定的回呼函式。
$collection = collect(['Michael', 'Tom']); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}); $collection->all(); // ['Michael', 'Tom'] $collection = collect(); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}); $collection->all(); // ['Adam']
可以將第二個閉包傳遞給 whenEmpty 方法,當集合不為空時將會執行該閉包。
$collection = collect(['Michael', 'Tom']); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}, function (Collection $collection) { return $collection->push('Taylor');}); $collection->all(); // ['Michael', 'Tom', 'Taylor']
如需 whenEmpty 的相反操作,請參閱 whenNotEmpty 方法。
whenNotEmpty()
當集合不為空時,whenNotEmpty 方法將執行給定的回呼函式。
$collection = collect(['michael', 'tom']); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}); $collection->all(); // ['michael', 'tom', 'adam'] $collection = collect(); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}); $collection->all(); // []
可以將第二個閉包傳遞給 whenNotEmpty 方法,當集合為空時將會執行該閉包。
$collection = collect(); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}, function (Collection $collection) { return $collection->push('taylor');}); $collection->all(); // ['taylor']
如需 whenNotEmpty 的相反操作,請參閱 whenEmpty 方法。
where()
where 方法會依據給定的鍵/值對來篩選集合。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->where('price', 100); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ]*/
where 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串將被視為等於相同值的整數。使用 whereStrict 方法以使用「嚴格」比較進行過濾。
或者,您可以傳遞比較運算子作為第二個參數。支援的運算子為:'===', '!==', '!=', '==', '=', '<>', '>', '<', '>=' 和 '<='。
$collection = collect([ ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], ['name' => 'Sue', 'deleted_at' => null],]); $filtered = $collection->where('deleted_at', '!=', null); $filtered->all(); /* [ ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], ]*/
whereStrict()
此方法與 where 方法具有相同的簽名;但是,所有值都會使用「嚴格」比較進行比較。
whereBetween()
whereBetween 方法會透過判斷指定的項目值是否在給定的範圍內來篩選集合。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 80], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Pencil', 'price' => 30], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereBetween('price', [100, 200]); $filtered->all(); /* [ ['product' => 'Desk', 'price' => 200], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]*/
whereIn()
whereIn 方法會從集合中移除不具有指定的項目值且該值未包含在給定陣列中的元素。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Desk', 'price' => 200], ['product' => 'Bookcase', 'price' => 150], ]*/
whereIn 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串將被視為等於相同值的整數。使用 whereInStrict 方法以使用「嚴格」比較進行過濾。
whereInStrict()
此方法與 whereIn 方法具有相同的簽名;但是,所有值都會使用「嚴格」比較進行比較。
whereInstanceOf()
whereInstanceOf 方法會依據給定的類別類型來篩選集合。
use App\Models\User;use App\Models\Post; $collection = collect([ new User, new User, new Post,]); $filtered = $collection->whereInstanceOf(User::class); $filtered->all(); // [App\Models\User, App\Models\User]
whereNotBetween()
whereNotBetween 方法會透過判斷指定的項目值是否在給定的範圍外來篩選集合。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 80], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Pencil', 'price' => 30], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereNotBetween('price', [100, 200]); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 80], ['product' => 'Pencil', 'price' => 30], ]*/
whereNotIn()
whereNotIn 方法會從集合中移除具有指定的項目值且該值包含在給定陣列中的元素。
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereNotIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ]*/
whereNotIn 方法在檢查項目值時使用「寬鬆」比較,這表示具有整數值的字串將被視為等於相同值的整數。使用 whereNotInStrict 方法以使用「嚴格」比較進行過濾。
whereNotInStrict()
此方法與 whereNotIn 方法具有相同的簽名;但是,所有值都會使用「嚴格」比較進行比較。
whereNotNull()
whereNotNull 方法會從集合中傳回給定鍵不為 null 的項目。
$collection = collect([ ['name' => 'Desk'], ['name' => null], ['name' => 'Bookcase'],]); $filtered = $collection->whereNotNull('name'); $filtered->all(); /* [ ['name' => 'Desk'], ['name' => 'Bookcase'], ]*/
whereNull()
whereNull 方法會從集合中傳回給定鍵為 null 的項目。
$collection = collect([ ['name' => 'Desk'], ['name' => null], ['name' => 'Bookcase'],]); $filtered = $collection->whereNull('name'); $filtered->all(); /* [ ['name' => null], ]*/
wrap()
靜態 wrap 方法會在適用時將給定的值包裝在集合中。
use Illuminate\Support\Collection; $collection = Collection::wrap('John Doe'); $collection->all(); // ['John Doe'] $collection = Collection::wrap(['John Doe']); $collection->all(); // ['John Doe'] $collection = Collection::wrap(collect('John Doe')); $collection->all(); // ['John Doe']
zip()
zip 方法會將給定陣列的值與原始集合中其對應索引的值合併在一起。
$collection = collect(['Chair', 'Desk']); $zipped = $collection->zip([100, 200]); $zipped->all(); // [['Chair', 100], ['Desk', 200]]
高階訊息
集合也支援「高階訊息」,它們是用於對集合執行常見動作的捷徑。提供高階訊息的集合方法有:average、avg、contains、each、every、filter、first、flatMap、groupBy、keyBy、map、max、min、partition、reject、skipUntil、skipWhile、some、sortBy、sortByDesc、sum、takeUntil、takeWhile 和 unique。
每個高階訊息都可以作為集合實例上的動態屬性存取。例如,讓我們使用 each 高階訊息來呼叫集合中每個物件上的方法。
use App\Models\User; $users = User::where('votes', '>', 500)->get(); $users->each->markAsVip();
同樣地,我們可以利用 sum 高階訊息來收集使用者集合的「投票」總數。
$users = User::where('group', 'Development')->get(); return $users->sum->votes;
惰性集合
簡介
在深入了解 Laravel 的惰性集合之前,請先花一些時間熟悉 PHP 生成器。
為了補充已經功能強大的 Collection 類別,LazyCollection 類別利用 PHP 的 生成器,讓您可以在保持低記憶體使用量的同時處理非常大的資料集。
例如,假設您的應用程式需要處理一個數 GB 的日誌檔,同時利用 Laravel 的集合方法來解析日誌。與其一次將整個檔案讀入記憶體,可以使用惰性集合來在給定時間僅將檔案的一小部分保留在記憶體中。
use App\Models\LogEntry;use Illuminate\Support\LazyCollection; LazyCollection::make(function () { $handle = fopen('log.txt', 'r'); while (($line = fgets($handle)) !== false) { yield $line; }})->chunk(4)->map(function (array $lines) { return LogEntry::fromLines($lines);})->each(function (LogEntry $logEntry) { // Process the log entry...});
或者,假設您需要迭代 10,000 個 Eloquent 模型。當使用傳統的 Laravel 集合時,必須同時將所有 10,000 個 Eloquent 模型載入到記憶體中。
use App\Models\User; $users = User::all()->filter(function (User $user) { return $user->id > 500;});
然而,查詢建構器的 cursor 方法會傳回 LazyCollection 實例。這讓您仍然可以只對資料庫執行單一查詢,但也僅在記憶體中保留一個 Eloquent 模型。在此範例中,filter 回呼函數只有在我們實際個別迭代每個使用者時才會執行,從而大幅減少記憶體使用量。
use App\Models\User; $users = User::cursor()->filter(function (User $user) { return $user->id > 500;}); foreach ($users as $user) { echo $user->id;}
建立惰性集合
若要建立惰性集合實例,您應該將 PHP 生成器函式傳遞至集合的 make 方法。
use Illuminate\Support\LazyCollection; LazyCollection::make(function () { $handle = fopen('log.txt', 'r'); while (($line = fgets($handle)) !== false) { yield $line; }});
可列舉合約
Collection 類別上的幾乎所有方法都可以在 LazyCollection 類別上使用。這兩個類別都實作了 Illuminate\Support\Enumerable 介面,它定義了以下方法:
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 intersectAssoc 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
會變更集合的方法(例如 shift、pop、prepend 等)在 LazyCollection 類別上無法使用。
惰性集合方法
除了在 Enumerable 介面中定義的方法之外,LazyCollection 類別還包含下列方法:
takeUntilTimeout()
takeUntilTimeout 方法會傳回一個新的惰性集合,該集合將列舉值直到指定的時間。在那時間之後,集合將停止列舉。
$lazyCollection = LazyCollection::times(INF) ->takeUntilTimeout(now()->addMinute()); $lazyCollection->each(function (int $number) { dump($number); sleep(1);}); // 1// 2// ...// 58// 59
為了說明此方法的使用方式,假設有一個應用程式使用游標從資料庫提交發票。您可以定義一個排程任務,每 15 分鐘執行一次,且最多只處理 14 分鐘的發票。
use App\Models\Invoice;use Illuminate\Support\Carbon; Invoice::pending()->cursor() ->takeUntilTimeout( Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes') ) ->each(fn (Invoice $invoice) => $invoice->submit());
tapEach()
雖然 each 方法會立即為集合中的每個項目呼叫給定的回呼函數,但 tapEach 方法只會在項目被一個接一個地從列表中拉出時才呼叫給定的回呼函數。
// Nothing has been dumped so far...$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) { dump($value);}); // Three items are dumped...$array = $lazyCollection->take(3)->all(); // 1// 2// 3
throttle()
throttle 方法會節流惰性集合,使得每個值在指定的秒數後才會傳回。此方法對於您可能正在與速率限制傳入請求的外部 API 互動的情況特別有用。
use App\Models\User; User::where('vip', true) ->cursor() ->throttle(seconds: 1) ->each(function (User $user) { // Call external API... });
remember()
remember 方法會傳回一個新的惰性集合,該集合會記住任何已經列舉的值,並且不會在後續的集合列舉中再次擷取它們。
// No query has been executed yet...$users = User::cursor()->remember(); // The query is executed...// The first 5 users are hydrated from the database...$users->take(5)->all(); // First 5 users come from the collection's cache...// The rest are hydrated from the database...$users->take(20)->all();