集合是Laravel 中提供的最強大的功能之一,集合本質上是由功能強大的數組組成。javascript
把相似數組的對象應用到方法中是頗有用的,經過鏈式編程,用極短的代碼,就能夠達到預期的效果。php
須要注意的是集合並非Laravel 中獨有的,許多語言均可以在數組中使用集合式編程,但很是遺憾,原生的PHP 是不支持集合式編程的,不過幸運的是,一些勤勞的人已經爲咱們完成了艱苦的工做,並編寫了一個很是方便的包——illuminate/support、Tightenco/Collect 。java
通常來講,集合是不可改變的,這意味着大部分 Collection 方法都會返回一個全新的 Collection 實例。laravel
爲了建立一個集合,能夠將一個數組傳入集合的構造器中,也能夠建立一個空的集合,而後把元素寫到集合中。Laravel 有collect()
助手,這是最簡單的,新建集合的方法。git
$collection = collect([1, 2, 3]);
默認狀況下, Eloquent 查詢的結果返回的內容都是Illuminate\Support\Collection
實例,若是但願對結果進行序列化,可使用toArray()
、toJson()
方法。
在非Laravel 項目中使用集合:github
安裝:編程
composer require illuminate/support
使用:數組
<?php // 引入package require __DIR__ . '/vendor/autoload.php'; $collection = collect([1, 2, 3]); var_dump($collection);
記住,全部方法均可以使用鏈式編程的方式優雅的操縱數組。並且幾乎全部的方法都會返回新的 Collection
實例,閉包
返回該集合表示的底層數組。composer
collect(["boo", "yumi", "mac"])->all(); // [「boo」, "yumi", "mac"]
獲取數組的平均值:
collect([1, 1, 2, 4])->avg(); // 2
獲取二維數組的平均值:
collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo'); // 20
avg()
是average()
的別名,二者的效果是同樣的。
將大集合按指定大小拆分紅小集合。
$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->toArray(); // [[1, 2, 3, 4], [5, 6, 7]]
根據指定的回調值把集合分解成多個更小的集合:
$collection = collect(str_split('AABBCCCD')); $chunks = $collection->chunkWhile(function ($current, $key, $chunk) { return $current === $chunk->last(); }); $chunks->all(); // [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
將多個數組合併成一個集合。
$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]
將一個集合的值做爲「鍵」,再將另外一個數組或者集合的值做爲「值」合併成一個集合。
$collection = collect(['name', 'age']); $combined = $collection->combine(['boo', 25]); $combined->all(); // ['name' => 'boo', 'age' => 25]
返回一個包含當前集合所含元素的新的 Collection 實例:
$collection = collect([1, 2, 3]); $collection->all(); // [1,2,3]
在集合的末端附加指定的數組或集合值:
$collection = collect(['John Doe']); $concatenated = $collection->concat(['Boo'])->concat(['name' => 'Yumi']); $concatenated->all(); // ['John Doe', 'Boo', 'Yumi']
判斷集合是否包含給定的項目。
基本用法:
$collection = collect(['name' => 'boo', 'age' => 25]); $collection->contains('boo'); // true $collection->contains('yumi'); // false
也能夠用 contains 方法匹配一對鍵/值,即判斷給定的配對是否存在於集合中:
$collection = collect([ ['name' => 'boo', 'age' => 25], ['name' => 'yumi', 'age' => 23], ]); $collection->contains("name", "mac"); // false
也能夠傳遞一個回調到 contains 方法來執行本身的真實測試:
$collection = collect([1, 2, 3, 4, 5]); // $value: 1 $key: 0 $collection->contains(function ($value, $key) { return $value > 5; }); // false
contains 方法在檢查項目值時使用「寬鬆」比較,意味着具備整數值的字符串將被視爲等於相同值的整數。 相反 containsStrict 方法則是使用「嚴格」比較進行過濾。
使用「嚴格模式」判斷集合是否包含給定的項目:
基本使用:
$collection = collect([ ['name' => 'boo', 'age' => 25], ['name' => 'yumi', 'age' => 23], ]); $collection->containsStrict("age", "25"); // false
如上例所示,數組值存在,可是值類型不一致也返回false。
返回該集合內的項目總數。
collect([1, 2, 3, 4])->count(); // 4
統計集合中每一個元素出現的次數。
基本用法:
$collection = collect([1, 2, 2, 2, 3, 5, 5]); $counted = $collection->countBy(); $counted->all(); // [1 => 1, 2 => 3, 3 => 1, 5=>2]
進階用法,自定義規則,統計元素出現的次數:
$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']); $counted = $collection->countBy(function ($email) { return substr(strrchr($email, "@"), 1); }); $counted->all(); // ['gmail.com' => 2, 'yahoo.com' => 1]
返回指定集合的可能的笛卡爾積。
$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'], ] */
備份文件系統和中止系統(dump and die)的縮寫,打印集合元素並中斷腳本執行。
$collection = collect(['John Doe', 'Jane Doe']); $collection->dd();
若是不想中斷執行腳本,請使用dump
方法替代。
與給定的集合或者數組進行比較,基於值求差集。
將集合與其它集合或純 PHP 數組進行值的比較,而後返回原集合中存在而給定集合中不存在的值:
$collection = collect([1, 2, 3, 4, 5]); $collection->diff([2, 4, 6, 8])->all(); // [1, 3, 5]
與給定的集合或者數組進行比較,基於鍵值對求差集。
返回原集合不存在於給定集合中的鍵值對:
$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]
與給定的集合或者數組進行比較,基於鍵求差集。
返回原集合中存在而給定的集合中不存在「鍵」所對應的鍵值對:
$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]
從集合中檢索並返回重複的值。
基本用法:
$collection = collect(['a', 'b', 'a', 'c', 'b']); $collection->duplicates(); // [2 => 'a', 4 => 'b']
若是集合包含數組或對象,則能夠傳遞但願檢查重複值的屬性的鍵:
$employees = collect([ ['email' => 'abigail@example.com', 'position' => 'Developer'], ['email' => 'james@example.com', 'position' => 'Designer'], ['email' => 'victoria@example.com', 'position' => 'Developer'], ]) $employees->duplicates('position'); // [2 => 'Developer']
duplicates
方法在檢查項目值時使用「寬鬆」比較,相反duplicatesStrict
方法則是使用「嚴格」比較進行過濾。
迭代集合中的內容並將其傳遞到回調函數中。
$collection = $collection->each(function ($item, $key) { // 若是要中斷對內容的迭代,那就從回調中返回 false if (/* some condition */) { return false; } });
一樣是遍歷集合,不過與each 的區別在於,對於多維數組,能夠直接拿到元素。
$collection = collect([['Boo', 25, "men"], ['Yumi', 23, "woman"]]); $collection->eachSpread(function ($name, $age, $gender) { var_dump($name, $age, $gender); // Boo、2五、men // Yumi、2三、woman }); $collection->each(function ($item, $key){ // 一樣能夠在回調函數中,返回false ,終止循環 var_dump($item, $key); }); /* array(3) { [0]=> string(3) "Boo" [1]=> int(25) [2]=> string(3) "men" } */
檢查集合中的每個元素是否經過指定條件:
collect([1, 2, 3, 4])->every(function ($value, $key) { return $value > 2; }); // false
注意:若是集合爲空, every 將返回 true。
返回集合中除了指定鍵之外的全部項目。
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]); $filtered = $collection->except(['price', 'discount']); $filtered->all(); // ['product_id' => 1]
與之相反的方法是 only()
。
使用給定的回調函數過濾集合的內容,只留下那些經過的元素。
$collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function ($value, $key) { // 當閉包返回true 時,保留一個條目 return $value > 2; }); $filtered->all(); // [3, 4]
若是沒有提供回調函數,集合中全部返回false的元素都會被移除:
$collection = collect([1, 2, 3, null, false, '', 0, []]); $collection->filter()->all(); // [1, 2, 3]
與之相反的方法是 reject()
。
返回集合中的第一個元素。
基本用法:
collect([1, 2, 3, 4])->first(); // 1
一樣能夠傳入回調函數,進行條件限制:
collect([1, 2, 3, 4])->first(function ($value, $key) { // 當閉包返回true 時,保留一個條目 return $value > 2; }); // 3
若是須要返回最後一個元素可使用last()
方法。
返回集合中含有指定鍵 / 值對的第一個元素:
$collection = collect([ ['name' => 'Regena', 'age' => null], ['name' => 'Linda', 'age' => 14], ['name' => 'Diego', 'age' => 23], ['name' => 'Linda', 'age' => 84], ]); // 返回name = Linda 的第一個元素 $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]
遍歷集合並將其中的每一個值傳遞到給定的回調。
能夠經過回調修改每一個值的內容再返回出來,從而造成一個新的被修改過內容的集合:
$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'];
將多維集合轉爲一維。
基本用法:
$collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]); $collection->flatten()->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'], ] */
在這個例子裏,調用 flatten 方法時不傳入深度參數的話也會將嵌套數組轉成一維的,而後返回 ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']
,傳入深度參數能限制設置返回數組的層數。
鍵值反轉。
$collection = collect(["name" => "boo", "age" => 25]); $collection->flip()->all(); // ["boo" => "name", 25 => "age"]
經過給定的鍵來移除掉集合中對應的內容。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $collection->forget('name'); $collection->all(); // ['framework' => 'laravel']
與大多數集合的方法不一樣,forget()
不會返回修改事後的新集合;它會直接修改原來的集合。
返回給定鍵的項目。
基本用法,若是該鍵不存在,則返回 null:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('name'); // taylor
能夠傳遞第二個參數做爲默認值:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('foo', 'boo'); // boo
甚至能夠將回調函數看成默認值。若是指定的鍵不存在,就會返回回調的結果:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $collection->get('email', function () { return 'boo'; }); // boo
根據給定的鍵對集合內的項目進行分組。
基本用法:
$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'], ], ] */
一樣能夠傳入一個回調函數來代替字符串的『鍵』,根據該回調函數的返回值來進行分組:
$grouped = $collection->groupBy(function ($item, $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 ($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']], ], ], ]; */
判斷集合中是否存在給定的鍵。
$collection = collect(["name" => "boo", "age" => 25]); $collection->has("name"); // true
合併集合中的項目。
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'
從原集合中移除不在給定數組或集合中的『任何值』,返回新的集合將保留原集合的鍵。
$collection = collect(['Desk', 'Sofa', 'Chair']); $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); $intersect->all(); // [0 => 'Desk', 2 => 'Chair']
刪除原集合中不存在於給定數組或集合中的『任何鍵』,返回新的集合將保留原集合的鍵。
$collection = collect([ 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009, ]); $intersect = $collection->intersectByKeys([ 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011, ]); $intersect->all(); // ['type' => 'screen', 'year' => 2009]
判斷集合是否爲空。
collect([])->isEmpty(); // true
判斷集合是否不爲空。
collect([])->isEmpty(); // false
將集合中的值用字符串鏈接。
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 '); // ''
以給定的鍵做爲集合的鍵。
$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'], ] */
返回集合的全部鍵。
$collection = collect(["name" => "boo", "age" => 25]); $collection->keys()->all(); // ["name", "age"]
返回集合中經過給定真實測試的最後一個元素,與first
方法正好相反。
collect([1, 2, 3, 4])->last(function ($value, $key) { return $value < 3; }); // 2
遍歷集合並將每個值傳入給定的回調,返回新的集合。
$collection = collect([1, 2, 3, 4, 5]); $multiplied = $collection->map(function ($item, $key) { return $item * 2; }); $multiplied->all(); // [2, 4, 6, 8, 10]
與其餘大多數集合方法同樣, map 會返回一個新的集合實例;它不會修改原集合。若是你想修改原集合,請使用 transform
方法。
經過指定回調函數對集合進行分組,
$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->all(); /* [ 'Sales' => ['John Doe', 'Jane Doe'], 'Marketing' => ['Johnny Doe'], ] */ $grouped->get('Sales')->all(); // ['John Doe', 'Jane Doe']
遍歷集合並將每一個值傳入給定的回調。
返回指定鍵的最大值。
$max = collect([['foo' => 10], ['foo' => 20]])->max('foo'); // 20 $max = collect([1, 2, 3, 4, 5])->max(); // 5
返回指定鍵的中間值。
$median = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo'); // 15 $median = collect([1, 1, 2, 4])->median(); // 1.5
將給定數組或集合合併到原集合。
若是給定的集合項的字符串鍵與原集合中的字符串鍵相匹配,則指定集合項的值將覆蓋原集合的值:
$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 = collect([1, 2, 3, 4, 5])->min(); // 1
返回指定鍵的衆數值。
collect([1, 1, 2, 4])->mode(); // [1]
每隔n個元素取一個元素組成一個新的集合。
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']); $collection->nth(4); // ['a', 'e'] // 第二個參數能夠做爲偏移位置 $collection->nth(4, 1); // ['b', 'f']
返回集合中給定鍵的全部項目。
$collection = collect(['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]); $filtered = $collection->only(['product_id', 'name']); $filtered->all(); // ['product_id' => 1, 'name' => 'Desk']
配合list()方法區分回調函數知足和不知足的數據。
$collection = collect([1, 2, 3, 4, 5, 6]); list($underThree, $equalOrAboveThree) = $collection->partition(function ($i) { return $i < 3; }); $underThree->all(); // [1, 2] $equalOrAboveThree->all(); // [3, 4, 5, 6]
將集合傳給給定的回調並返回結果。
$collection = collect([1, 2, 3]); $piped = $collection->pipe(function ($collection) { return $collection->sum(); }); // 6
獲取集合中給定鍵對應的全部值。
基本用法:
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk', "id" => 1], ['product_id' => 'prod-200', 'name' => 'Chair', "id" => 2], ]); $plucked = $collection->pluck('name'); $plucked->all(); // ['Desk', 'Chair']
還能夠傳入第二個參數做爲鍵值:
$plucked = $collection->pluck('name', "id"); $plucked->all(); // [1 => 'Desk', 2 => 'Chair']
移除並返回集合中的最後一個項目。
將給定的值添加到集合的開頭。
把給定鍵對應的值從集合中移除並返回。
把給定值添加到集合的末尾。
在集合內設置給定的鍵值對。
從集合中返回一個隨機項。
將每次迭代的結果傳遞給下一次迭代直到集合減小爲單個值。
使用指定的回調過濾集合。
倒轉集合中項目的順序。
搜索給定的值並返回它的鍵。
移除並返回集合的第一個項目。
隨機排序集合中的項目。
返回集合中給定值後面的部分。
保留原數組的鍵,對集合進行排序。
以給定的鍵對集合進行排序。
與sortBy同樣,以相反的順序來對集合進行排序。
刪除並返回從給定值後的內容,原集合也會受到影響。
將集合按給定的值拆分。
返回集合內全部項目的總和。
返回給定數量項目的新集合。
將集合傳遞給回調,在特定點「tap」集合。
經過回調在給定次數內建立一個新的集合。
將集合轉換成 PHP 數組。
將集合轉換成 JSON 字符串。
迭代集合並對集合內的每一個項目調用給定的回調。
將給定的數組添加到集合中。
返回集合中全部惟一的項目。
使用嚴格模式返回集合中全部惟一的項目。
返回鍵被重置爲連續編號的新集合。
當傳入的第一個參數爲 true 的時,將執行給定的回調。
經過給定的鍵值過濾集合。
使用嚴格模式經過給定的鍵值過濾集合。
經過給定的鍵值數組來過濾集合。
使用嚴格模式經過給定的鍵值數組來過濾集合。
集合中不包含的給定鍵值對進行匹配。
使用嚴格模式經過集合中不包含的給定鍵值對進行匹配。
將給定數組的值與相應索引處的原集合的值合併在一塊兒。