集合

集合


集合

简介

Illuminate\Support\Collection类提供了一个更具可读性和更便于处理数组数据的封装。具体例子请查看下面代码。我们使用collect辅助函数从数组中创建一个新的集合实例,对其中每一个元素执行strtoupper函数之后再删除所有的空元素:

$collection = collect(['taylor', 'abigail', null])->map(function ($name) { return strtoupper($name); })->reject(function ($name) { return empty($name); });

正如你所见,Collection类允许你链式调用其它方法,以达到在底层数组上流畅的执行 map 和 reduce 操作,通常,集合是不可变的,这意味着每一个Collection方法都会返回一个新的Collection实例。

创建集合

如上所述,collect辅助函数会为指定的数组返回一个新的Illuminate\Support\Collection实例。因此,我们可以这样轻松的创建一个集合:

$collection = collect([1, 2, 3]);

{tip} 通常,Eloquent 查询的结果返回的内容都是Collection实例。

扩展集合

集合都是「可宏扩展」(macroable) 的,它允许你在执行时将其它方法添加到Collection类。例如,通过下面的代码在Collection类中添加一个toUpper方法:

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']

通常,你应该在 服务提供者 内声明集合宏。

可用方法

接下来的文档内容,我们会探讨Collection类的每个方法。请牢记,所有方法都可以通过链式访问的形式优雅的操作数组。而且,几乎所有的方法都会返回一个新的Collection实例,允许你在必要时保存集合的原始副本:

all
average
avg
chunk
collapse
combine
concat
contains
containsStrict
count
crossJoin
dd
diff
diffAssoc
diffKeys
dump
each
eachSpread
every
except
filter
first
firstWhere
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
some
sort
sortBy
sortByDesc
sortKeys
sortKeysDesc
splice
split
sum
take
tap
times
toArray
toJson
transform
union
unique
uniqueStrict
unless
unlessEmpty
unlessNotEmpty
unwrap
values
when
whenEmpty
whenNotEmpty
where
whereStrict
whereBetween
whereIn
whereInStrict
whereInstanceOf
whereNotBetween
whereNotIn
whereNotInStrict
wrap
zip

方法列表

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

chunk()

chunk方法将集合拆成多个给定大小的小集合:

$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->toArray(); // [[1, 2, 3, 4], [5, 6, 7]]

这个方法在使用网格系统的 视图 中特别适用,例如Bootstrap。 想象你有一个 Eloquent 模型的集合要在网格中显示:

@foreach ($products->chunk(3) as $chunk) 
@foreach ($chunk as $product)
{{ $product->name }}
@endforeach
@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方法在检查集合项的值时使用「宽松」比较,这意味着具有整数值的字符串将被视为等于相同值的整数。相反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(); /* Collection { #items: array:2 [ 0 => "John Doe" 1 => "Jane Doe" ] } */

如果你不想中断执行脚本,请使用dump方法代替。

diff()

diff方法将集合与其它集合或纯 PHP数组进行值的比较。然后返回原集合中存在而指定集合中不存在的值:

$collection = collect([1, 2, 3, 4, 5]); $diff = $collection->diff([2, 4, 6, 8]); $diff->all(); // [1, 3, 5]

diffAssoc()

diffAssoc方法与另外一个集合或基于它的键和值的 PHP数组进行比较。这个方法将会返回原集合不存在于指定集合的键 / 值对:

$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数组的键进行比较,然后返回原集合中存在而指定集合中不存在键所对应的键 / 值对:

$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->each(function ($item, $key) { // });

如果你想中断对集合项的循环,那么就在你的回调函数中返回false

$collection->each(function ($item, $key) { if (/* 某些条件 */ ) { 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

如果集合为空,every将返回 true:

$collection = collect([]); $collection->every(function($value, $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方法。

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

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 ($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'], ] */

在这个例子里,调用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']); $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'], ], ] */

可以传递一个数组用于多重分组标准。每一个数组元素将对应多维数组内的相应级别:

$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']], ], ], ]; */

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

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类。关于更多信息,请参阅扩展集合的文档。

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 ($even, $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 ($item, $key) { return [$item['department'] => $item['name']]; }); $grouped->toArray(); /* [ 'Sales' => ['John Doe', 'Jane Doe'], 'Marketing' => ['Johnny 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 = 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方法将使用给定的值填充数组,直到数组达到指定的大小。该方法的行为与array_padPHP 函数功能类似。

要填充到左侧,你应该使用负值。如果给定大小的绝对值小于或等于数组的长度,则不会发生填充:

$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, $equalOrAboveThree) = $collection->partition(function ($i) { return $i < 3; }); $underThree->all(); // [1, 2] $equalOrAboveThree->all(); // [3, 4, 5, 6]

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']

如果存在重复的键,则最后一个匹配元素将被插入到弹出的集合中:

$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]

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)

如果集合的项小于指定的数量,则该方法将抛出InvalidArgumentException

reduce()

reduce方法将每次迭代的结果传递给下一次迭代直到集合减少为单个值:

$collection = collect([1, 2, 3]); $total = $collection->reduce(function ($carry, $item) { return $carry + $item; }); // 6

第一次迭代时$carry的数值为null; however,你也可以通过传入第二个参数到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(['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作为该方法的第二个参数:

$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方法来重新建立索引。

some()

contains方法的别名。

sort()

sort方法对集合进行排序。排序后的集合会保留原数组的键,所以在这个例子我们将使用values方法去把键重置为连续编号的索引:

$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sort(); $sorted->values()->all(); // [1, 2, 3, 4, 5]

如果你有更高级的排序需求,可以通过自己的算法将回调函数传递到sort。请参阅 PHP 文档的uasort,这是集合的sort方法在底层所调用的。

{tip} 如果你需要对嵌套数组或对象进行排序,请参照sortBysortByDesc方法。

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方法一样,但是会以相反的顺序来对集合进行排序。

sortKeys()

sortKeys方法通过底层关联数组的键来对集合进行排序:

$collection = collect([ 'id' => 22345, 'first' => 'John', 'last' => 'Doe', ]); $sorted = $collection->sortKeys();$sorted->all(); /* [ 'first' => 'John', 'id' => 22345, 'last' => 'Doe', ] */

sortKeysDesc()

该方法与sortKeys方法一样,但是会以相反的顺序来对集合进行排序。

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方法将给定的回调函数传入该集合,允许你在一个特定点「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 No. $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方法。

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'

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方法。

whenEmpty()

whenEmpty方法当集合为空时,将执行给定的回调函数:

$collection = collect(['michael', 'tom']); $collection->whenEmpty(function ($collection) { return $collection->push('adam'); }); $collection->all(); // ['michael', 'tom'] $collection = collect();$collection->whenEmpty(function ($collection) { return $collection->push('adam'); }); $collection->all(); // ['adam'] $collection = collect(['michael', 'tom']); $collection->whenEmpty(function($collection) { return $collection->push('adam');}, function($collection) { return $collection->push('taylor'); }); $collection->all(); // ['michael', 'tom', 'taylor']

whenEmpty对应的是whenNotEmpty方法。

whenNotEmpty()

whenNotEmpty方法当集合不为空时,将执行给定的回调函数:

$collection = collect(['michael', 'tom']); $collection->whenNotEmpty(function ($collection) { return $collection->push('adam'); }); $collection->all(); // ['michael', 'tom', 'adam'] $collection = collect(); $collection->whenNotEmpty(function ($collection) { return $collection->push('adam'); }); $collection->all(); // [] $collection = collect(); $collection->whenNotEmpty(function($collection) { return $collection->push('adam'); }, function($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方法进行「严格」模式比较。

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' => 'Bookcase', 'price' => 150], ['product' => 'Desk', 'price' => 200], ] */

whereIn方法使用「宽松」的比较来检查集合项的值,这意味着具有整数值的字符串会被视为等于相同值的整数。你可以使用whereInStrict方法进行「严格」模式比较。

whereInStrict()

这个方法与whereIn方法类似;不同的是会使用「严格」模式进行比较。

whereInstanceOf()

whereInstanceOf方法根据指定的类来过滤集合:

$collection = collect([ new User, new User, new Post, ]); return $collection->whereInstanceOf(User::class);

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方法类似;不同的是会使用 「严格」模式作比较。

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,groupBy,keyBy,map,max,min,partition,reject,some,sortBy,sortByDesc,sum, andunique

每个高阶消息传递都能作为集合实例的动态的属性来访问。例如,使用each高阶消息传递在集合中的每个对象上调用一个方法:

$users = User::where('votes', '>', 500)->get(); $users->each->markAsVip();

同样,我们可以使用sum高阶消息传递来收集 users 集合中的「投票」总数:

$users = User::where('group', 'Development')->get(); return $users->sum->votes;
本文章首发在 LearnKu.com网站上。