集合
簡介
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();