集合
簡介
Illuminate\Support\Collection
類別提供一個流暢、便利的封裝來操控陣列資料。舉個例子,查看下列的程式碼。我們將用 collect
輔助方法從陣列建立一個新的集合實例,對每一個元素執行 strtoupper
函式,然後移除所有的空元素:
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
})
->reject(function ($name) {
return empty($name);
});
如你所見,Collection
類別允許你鏈結它的方法以對底層的陣列流暢地進行映射與刪減。一般來說,每一個 Collection
方法會回傳一個全新的 Collection
實例。
建立集合
如上所述,collect
輔助方法會用傳入的陣列回傳一個新的 Illuminate\Support\Collection
實例。所以要建立一個集合就這麼簡單:
$collection = collect([1, 2, 3]);
{tip} Eloquent 查詢結果,每次都會回傳
Collection
的實例。
擴充集合
每個集合都是可”巨集化”的,這允許你在程式運作期間增加額外的方法到集合內。以下程式碼示範了如何將toUpper
加進Collection
裡:
use Illuminate\Support\Str;
Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});
$collection = collect(['first', 'second']);
$upper = $collection->toUpper();
// ['FIRST', 'SECOND']
一般來說, 你可以將巨集定義在 service provider 裡.
可用的方法
在這份文件剩餘的部份,我們將會探討每一個 Collection
類別上可用的方法。要先知道的是,以下所有的方法,都可以用串鏈式的方式處理陣列。另外,大部分的方法都會回傳一個新的 Collection
實例,讓你在必要時,還有原始的數組可使用。
all average avg chunk collapse combine concat contains containsStrict count crossJoin dd diff diffAssoc diffKeys dump each eachSpread every except filter first flatMap flatten flip forget forPage get groupBy has implode intersect intersectByKeys isEmpty isNotEmpty keyBy keys last macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge min mode nth only pad partition pipe pluck pop prepend pull push put random reduce reject reverse search shift shuffle slice sort sortBy sortByDesc splice split sum take tap times toArray toJson transform union unique uniqueStrict unless unwrap values when where whereStrict whereIn whereInStrict whereNotIn whereNotInStrict wrap zip
方法清單
all()
{#collection-method .first-collection-method}
all
方法回傳該集合所代表的底層陣列:
collect([1, 2, 3])->all();
// [1, 2, 3]
average()
此為 avg
方法的別名。
avg()
avg
方法會回傳指定 key 所對應數值的平均值:
$average = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo');
// 20
$average = collect([1, 1, 2, 4])->avg();
// 2
chunk()
chunk
方法將集合拆成多個給定大小的較小集合:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->toArray();
// [[1, 2, 3, 4], [5, 6, 7]]
當你在 views 裡有使用像 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
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]
combine()
combine
方法將此一集合的值當成鍵值,與另一個陣列或集合的值結合成新的集合。
$collection = collect(['name', 'age']);
$combined = $collection->combine(['George', 29]);
$combined->all();
// ['name' => 'George', 'age' => 29]
concat()
concat
方法會將給定的陣列
或集合的值附加在此一集合之後。
$collection = collect(['John Doe']);
$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);
$concatenated->all();
// ['John Doe', 'Jane Doe', 'Johnny Doe']
contains()
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
方法內執行你自己的判斷式:
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function ($value, $key) {
return $value > 5;
});
// false
contains
方法使用弱型別比較
,所以當字串的內容是數字時,比較的結果會等於型態是 integer 的數字。可使用 containsStrict
方法改成強型別比較。
containsStrict()
這個方法的用法與 contains
相同,但所有數值都會用「嚴格模式」來比較。
count()
count
方法回傳該集合內的項目總數:
$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4
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();
/*
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]
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]
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]
dump()
dump
方法會傾印出此集合的所有元素:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
如果你想在傾印後停止執行程式,可使用 dd
方法代替。
each()
each
方法遍歷集合中的元素,並將之傳入給定的回呼函式:
$collection = $collection->each(function ($item, $key) {
//
});
如果你想在某個元素中斷迴圈,可以在回呼函式返回 false
$collection = $collection->each(function ($item, $key) {
if (/* some condition */) {
return false;
}
});
eachSpread()
eachSpread
方法遍歷集合中的元素,並將每個巢狀元素都傳給回呼函式:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);
$collection->eachSpread(function ($name, $age) {
//
});
如果你想在某個元素中斷迴圈,可以在回呼函式返回 false
:
$collection->eachSpread(function ($name, $age) {
return false;
});
every()
every
方法用於檢驗所有元素是否通過所給予的測試:
collect([1, 2, 3, 4])->every(function ($value, $key) {
return $value > 2;
});
// false
except()
except
方法回傳集合中排除指定鍵的所有項目:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);
$filtered = $collection->except(['price', 'discount']);
$filtered->all();
// ['product_id' => 1]
與 except
相反的方法請查看 only。
filter()
filter
方法以給定的回呼函式篩選集合,只留下那些通過判斷測試的項目:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function ($value, $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 ($value, $key) {
return $value > 2;
});
// 3
你也可以不傳入參數使用 first
方法以取得集合中第一個元素。如果集合是空的,則會回傳 null
:
collect([1, 2, 3, 4])->first();
// 1
flatMap()
flatMap
方法將集合內元素傳入回呼函式中,此回呼函式可對每個元素任意修改並回傳,從而形成一個修改過的新項目集合。該陣列會被扁平化成同一個層級:
$collection = collect([
['name' => 'Sally'],
['school' => 'Arkansas'],
['age' => 28]
]);
$flattened = $collection->flatMap(function ($values) {
return array_map('strtoupper', $values);
});
$flattened->all();
// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
flatten()
flatten
方法將多維集合轉為一維集合:
$collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]);
$flattened = $collection->flatten();
$flattened->all();
// ['taylor', 'php', 'javascript'];
你還可以帶入「深度」參數
$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'],
]
*/
在這例子中,若沒有傳入「深度」參數,將會得到['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']);
$collection->forget('name');
$collection->all();
// ['framework' => 'laravel']
{note} 與大多數的集合的方法不同,
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('foo', 'default-value');
// default-value
你甚至可以傳入回呼函式當預設值。如果指定的鍵不存在,就會回傳回呼函式的執行結果:
$collection->get('email', function () {
return 'default-value';
});
// default-value
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->toArray();
/*
[
'account-x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'account-x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
除了傳入字串的鍵
之外,你也可以傳入回呼函式。該函式應該回傳你希望用來分組的鍵的值。
$grouped = $collection->groupBy(function ($item, $key) {
return substr($item['account_id'], -3);
});
$grouped->toArray();
/*
[
'x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
has()
has
方法用來確認集合中是否含有給定的鍵:
$collection = collect(['account_id' => 1, 'product' => 'Desk']);
$collection->has('product');
// true
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'
intersect()
intersect
方法移除任何給定陣列
或集合內所沒有的數值。
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
intersectByKeys()
intersectByKeys
方法從原始集合中移除任何給定陣列
或集合內所沒有的鍵值。
$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
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 ($item) {
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 ($value, $key) {
return $value < 3;
});
// 2
你也可以不傳入參數使用 last
方法以取得集合中最後一個元素。如果集合是空的,則會回傳 null
:
collect([1, 2, 3, 4])->last();
// 4
macro()
靜態的 macro
方法,允許你在執行期間動態加入 Collection
類別內。可參考 extending collections 章節獲得更多資訊。
make()
靜態的 make
方法,可產生新的集合,見 建立集合 章節。
map()
map
方法遍歷整個集合並將每一個數值傳入給定的回呼函式。回呼函式可以任意修改並回傳項目,從而形成一個修改過的新項目集合:
$collection = collect([1, 2, 3, 4, 5]);
$multiplied = $collection->map(function ($item, $key) {
return $item * 2;
});
$multiplied->all();
// [2, 4, 6, 8, 10]
{note} 如同大多數的集合方法一樣,
map
回傳一個新集合實例。它並沒有修改到原本的集合。假如你想改變原始的集合,得使用transform
方法。
mapInto()
mapInto()
方法遍歷整個集合,並將每個值傳入指定類別實體的建構子中:
class Currency
{
/**
* Create a new currency instance.
*
* @param string $code
* @return void
*/
function __construct(string $code)
{
$this->code = $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 ($odd, $even) {
return $odd + $even;
});
$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 ($item, $key) {
return [$item['department'] => $item['name']];
});
$grouped->toArray();
/*
[
'Sales' => ['John Doe', 'Jane Doe'],
'Marketing' => ['Johhny Doe'],
]
*/
$grouped->get('Sales')->all();
// ['John Doe', 'Jane Doe']
mapWithKeys()
mapWithKeys
方法遍歷整個集合並將每個數值(包含鍵)傳進回呼函式。該回呼函式會回傳只包含一對鍵與值的組合:
$collection = collect([
[
'name' => 'John',
'department' => 'Sales',
'email' => 'john@example.com'
],
[
'name' => 'Jane',
'department' => 'Marketing',
'email' => 'jane@example.com'
]
]);
$keyed = $collection->mapWithKeys(function ($item) {
return [$item['email'] => $item['name']];
});
$keyed->all();
/*
[
'john@example.com' => 'John',
'jane@example.com' => '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']
min()
min
方法會回傳給定鍵的最小值:
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1
mode()
mode
方法會回傳給定鍵中最常出現的數值(mode value):
$mode = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo');
// [10]
$mode = collect([1, 1, 2, 4])->mode();
// [1]
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。
pad()
pad
方法會用給定的值補滿至給定的大小。這方法類似於 PHP 的函式 array_pad。
如果要往左邊填滿,可以傳入一個負數大小。若給定的大小小於等於目前陣列的大小,則不會有任何填充:
$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 函式 list
結合使用。
$collection = collect([1, 2, 3, 4, 5, 6]);
list($underThree, $aboveThree) = $collection->partition(function ($i) {
return $i < 3;
});
pipe()
pipe
方法將此集合傳入回呼函式中,並回傳其結果:
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function ($collection) {
return $collection->sum();
});
// 6
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']
pop()
pop
方法移除並回傳集合最後一個項目:
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop();
// 5
$collection->all();
// [1, 2, 3, 4]
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 = $collection->random(3);
$random->all();
// [2, 4, 5] - (retrieved randomly)
reduce()
reduce
方法將集合縮減到單一數值,該方法會將每次迭代的結果傳入到下一次迭代:
$collection = collect([1, 2, 3]);
$total = $collection->reduce(function ($carry, $item) {
return $carry + $item;
});
// 6
第一次迭代時 $carry
的數值為 null
;然而你也可以傳入第二個參數進 reduce
以指定它的初始值:
$collection->reduce(function ($carry, $item) {
return $carry + $item;
}, 4);
// 10
reject()
reject
方法以給定的回呼函式篩選集合。該回呼函式應該對希望從最終集合移除掉的項目回傳 true
:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function ($value, $key) {
return $value > 2;
});
$filtered->all();
// [1, 2]
與 reject
相對的方法可以檢視 filter
方法。
reverse()
reverse
方法倒轉集合內項目的順序:
$collection = collect([1, 2, 3, 4, 5]);
$reversed = $collection->reverse();
$reversed->all();
// [5, 4, 3, 2, 1]
search()
search
方法在集合內搜尋給定的數值並回傳找到的鍵。假如找不到項目,則回傳 false
:
$collection = collect([2, 4, 6, 8]);
$collection->search(4);
// 1
搜尋是用「寬鬆」比對來進行。這意味著字串型態的數字會等於有相同數值的數字。要使用嚴格比對,就傳入 true
為該方法的第二個參數:
$collection->search('4', true);
// false
另外,你可以傳入你自己的回呼函式來搜尋第一個通過你判斷測試的項目:
$collection->search(function ($item, $key) {
return $item > 5;
});
// 2
shift()
shift
方法移除並回傳集合的第一個項目:
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift();
// 1
$collection->all();
// [2, 3, 4, 5]
shuffle()
shuffle
方法隨機排序集合的項目:
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (generated randomly)
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
方法重設為連續的數字索引。
sort()
sort
方法對集合排序。排序過的集合保有原來的陣列鍵。在這個例子中我們用了 values
方法重設鍵為連續的數字索引。
$collection = collect([5, 3, 1, 2, 4]);
W$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
假如你需要更進階的排序,你可以傳入回呼函式以你自己的演算法進行排序
。參考 PHP 文件的 usort
,這是集合的 sort
方法在背後所使用的函式。
{tip} 要排序內含陣列或物件的集合,見
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],
]
*/
你也可以傳入自己的回呼函式以決定如何排序集合數值:
$collection = collect([
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$sorted = $collection->sortBy(function ($product, $key) {
return count($product['colors']);
});
$sorted->values()->all();
/*
[
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]
*/
sortByDesc()
這個方法與 sortBy
有著一樣的形式,但是會以相反的順序來排序集合。
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->toArray();
// [[1, 2], [3, 4], [5]]
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 ($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]
tap()
tap
方法將集合傳入給定的回呼函式,允許你在適當的時機”引出”裡面的元素,且做任何事都不會影響到原有的集合:
collect([2, 4, 3, 1, 5])
->sort()
->tap(function ($collection) {
Log::debug('Values after sorting', $collection->values()->toArray());
})
->shift();
// 1
times()
times
這個靜態函式,會以一個參數為次數的回呼函式,創建一個新的集合:
$collection = Collection::times(10, function ($number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
這個方法與產生 Eloquent 模型的工廠結合會非常好用。
$categories = Collection::times(3, function ($number) {
return factory(Category::class)->create(['name' => 'Category #'.$number]);
});
$categories->all();
/*
[
['id' => 1, 'name' => 'Category #1'],
['id' => 2, 'name' => 'Category #2'],
['id' => 3, 'name' => 'Category #3'],
]
*/
toArray()
toArray
方法將集合轉換成純 PHP 陣列
。假如集合的數值是 Eloquent 模型,也會被轉換成陣列:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/
{note}
toArray
也會轉換所有內嵌的物件為陣列。假如你希望取得原本的底層陣列,改用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 ($item, $key) {
return $item * 2;
});
$collection->all();
// [2, 4, 6, 8, 10]
{note} 與大多數其他集合的方法不同,
transform
會修改集合本身。如果你希望建立新集合,就改用map
方法。
union()
union
方法會將傳入的陣列加進集合中。如果傳入陣列索引跟原始集合重複,則會優先使用原始集合的值:
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['b']]);
$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 = $collection->unique(function ($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
方法做嚴格比對。
uniqueStrict()
此方法的特徵都與 unique
方法相同,但所有數值將會以嚴格模式來比較。
unless()
unless
方法會在第一個參數為 true
時執行回呼函式:
$collection = collect([1, 2, 3]);
$collection->unless(true, function ($collection) {
return $collection->push(4);
});
$collection->unless(false, function ($collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
與 unless
相對的方法可檢視when
。
unwrap()
unwrap
靜態方法會回以最適當的值回傳其最根本的元素。
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'
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()
when
會在第一個參數為 true
時執行回呼函式:
$collection = collect([1, 2, 3]);
$collection->when(true, function ($collection) {
return $collection->push(4);
});
$collection->when(false, function ($collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 4]
與 when
相對的方法可檢視 unless
。
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
方法做嚴格比對。
whereStrict()
這方法與 where
方法有相同的行為,但都是以嚴格模式比對所有值。
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' => 'Bookcase', 'price' => 150],
['product' => 'Desk', 'price' => 200],
]
*/
whereIn
方法是用「寬鬆」比對來進行。這意味著字串型態的數字會等於有相同數值的數字。可使用 whereInStrict
方法做嚴格比對。
whereInStrict()
這方法與 whereIn
方法有相同的行為,但都是以嚴格模式比對所有值。
whereNotIn()
whereIn
方法以給定的鍵/多個數值篩選不存在在集合內的值:
$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
方法有相同的行為,但都是以嚴格模式比對所有值。
wrap()
wrap
靜態方法將給定的值包進集合內:
$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
,map
,partition
,reject
,sortBy
,sortByDesc
和 sum
。
每個高階訊息傳遞像是存取集合的動態屬性一樣。例如,我們用高階訊息傳遞的 each
來讓集合內的每個元素都呼叫一個方法:
$users = User::where('votes', '>', 500)->get();
$users->each->markAsVip();
同樣的,我們可以用sum
高階訊息傳遞去收集集合內使用者的「votes」總數:
$users = User::where('group', 'Development')->get();
return $users->sum->votes;