集合
简介
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]);
Eloquent 查询结果始终返回
Collection
实例。
扩展集合
集合还可以「定义宏」,允许在运行时为 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
sort
sortBy
sortByDesc
sortKeys
sortKeysDesc
splice
split
sum
take
tap
times
toArray
toJson
transform
union
unique
uniqueStrict
unless
unwrap
values
when
where
whereStrict
whereIn
whereInStrict
whereInstanceOf
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)
<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
方法在检查项目值时使用「宽松」比较,意味着整数值字符串会被认为与有相同值的整数相等。可以使用 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
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' => 12],
['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]
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']
不像大多数其它集合方法,
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'],
],
]
*/
除了传递一个字符串的 key
,还可以传递一个回调。回调返回希望按此值分组的键:
$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
方法将集合中的所有项连接起来。方法参数取决于集合中的项的类型。如果集合包含数组或者对象,应该传递希望连接的属性的键,以及希望在值之间放的字符串「glue」:
$collection = collect([
['account_id' => 1, 'product' => 'Desk'],
['account_id' => 2, 'product' => 'Chair'],
]);
$collection->implode('product', ', ');
// Desk, Chair
如果集合包含简单的字符串或数字值,只用传递一个参数「glue」:
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]
像大多数其它方法一样,
map
返回一个新的集合实例;不改变调用的集合。如果要转换原集合,可以使用transform
方法。
mapInto()
mapInto()
方法迭代集合中的每一项,通过将值传递给构造函数来创建一个新的给定类的实例:
class Currency
{
/**
* 创建新的货币实例
*
* @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 = 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, $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()
pop
方法从集合中移除并返回指定键对应的项:
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);
$collection->pull('name');
// 'Desk'
$collection->all();
// ['product_id' => 'prod-100']
push()
push
方法在集合的最后追加一项:
The push
method appends an item to the end of the collection:
$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] - (随机获取)
如果集合的总项数小于请求数,此方法会抛出一个 InvalidArgumentException
。
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(['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] - (随机生成)
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]);
$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
如果有更高级的排序需求,可以将自己的算法作为回调传递给 sort
。参阅 PHP 文档的 uasort
,集合的 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],
]
*/
也可以传递自己的回调来决定如何对集合的值进行排序:
$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
方法将集合传递给指定回调,允许在指定位置访问集合并对其中的项进行不会影响集合本身的操作:
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],
]
*/
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]
不像大多数其它集合方法,
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
方法有相同的参数;但是,所有值比较时都使用「严格」比较。
whereInstanceOf()
whereInstanceOf
方法通过给定类的类型过滤集合:
$collection = collect([
new User,
new User,
new Post,
]);
return $collection->whereInstanceOf(User::class);
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]]
高阶信息
集合也支持「高阶信息(Higher Order Messages)」,即在集合上用快捷操作处理常用操作。支持高阶信息的集合方法有:average
,avg
,contains
,each
,every
,filter
,first
,flatMap
,groupBy
,keyBy
,map
,max
,min
,partition
,reject
,sortBy
,sortByDesc
,sum
和 unique
。
每个高阶信息都可以在集合实例上通过动态属性获取。例如,我们使用 each
高阶信息对集合中的每个对象调用一个方法:
$users = User::where('votes', '>', 500)->get();
$users->each->markAsVip();
同样的,我们可以使用 sum
高阶信息获取集合中所有用户的「投票」总数:
$users = User::where('group', 'Development')->get();
return $users->sum->votes;