# 集合

## 简介

`Illuminate\Support\Collection` 类提供一个流畅、便利的封装来操控数组数据。如下面的示例代码，我们用 `collect` 函数从数组中创建新的集合实例，对每一个元素运行 `strtoupper` 函数，然后移除所有的空元素：

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

### 创建集合

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

{tip} 默认 Eloquent 模型的查询结果总是以 `Collection` 实例返回。

## 方法清单

#### `all()`

``````collect([1, 2, 3])->all();

// [1, 2, 3]``````

#### `avg()`

``````collect([1, 2, 3, 4, 5])->avg();

// 3``````

``````\$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176],
['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
]);

\$collection->avg('pages');

// 636``````

#### `chunk()`

``````\$collection = collect([1, 2, 3, 4, 5, 6, 7]);

\$chunks = \$collection->chunk(4);

\$chunks->toArray();

// [[1, 2, 3, 4], [5, 6, 7]]``````

``````@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()`

``````\$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()`

``````\$collection = collect(['name', 'age']);

\$combined = \$collection->combine(['George', 29]);

\$combined->all();

// ['name' => 'George', 'age' => 29]``````

#### `contains()`

``````\$collection = collect(['name' => 'Desk', 'price' => 100]);

\$collection->contains('Desk');

// true

\$collection->contains('New York');

// false``````

``````\$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);

\$collection->contains('product', 'Bookcase');

// false``````

``````\$collection = collect([1, 2, 3, 4, 5]);

\$collection->contains(function (\$value, \$key) {
return \$value > 5;
});

// false``````

#### `count()`

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

\$collection->count();

// 4``````

#### `diff()`

``````\$collection = collect([1, 2, 3, 4, 5]);

\$diff = \$collection->diff([2, 4, 6, 8]);

\$diff->all();

// [1, 3, 5]``````

#### `diffKeys()`

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

#### `each()`

``````\$collection = \$collection->each(function (\$item, \$key) {
//
});``````

``````\$collection = \$collection->each(function (\$item, \$key) {
if (/* some condition */) {
return false;
}
});``````

#### `every()`

``````\$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);

\$collection->every(4);

// ['a', 'e']``````

``````\$collection->every(4, 1);

// ['b', 'f']``````

#### `except()`

``````\$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);

\$filtered = \$collection->except(['price', 'discount']);

\$filtered->all();

// ['product_id' => 1]``````

`except` 相反的方法请查看 only

#### `filter()`

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

\$filtered = \$collection->filter(function (\$value, \$key) {
return \$value > 2;
});

\$filtered->all();

// [3, 4]``````

`filter` 相反的方法可以查看 reject

#### `first()`

``````collect([1, 2, 3, 4])->first(function (\$value, \$key) {
return \$value > 2;
});

// 3``````

``````collect([1, 2, 3, 4])->first();

// 1``````

#### `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()`

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

#### `flip()`

``````\$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

\$flipped = \$collection->flip();

\$flipped->all();

// ['taylor' => 'name', 'laravel' => 'framework']``````

#### `forget()`

``````\$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

\$collection->forget('name');

\$collection->all();

// ['framework' => 'laravel']``````

{note} 与大多数其它集合的方法不同，`forget` 不会返回修改过后的新集合；它会直接修改调用它的集合。

#### `forPage()`

``````\$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);

\$chunk = \$collection->forPage(2, 3);

\$chunk->all();

// [4, 5, 6]``````

#### `get()`

``````\$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()`

``````\$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()`

``````\$collection = collect(['account_id' => 1, 'product' => 'Desk']);

\$collection->has('email');

// 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()`

``````\$collection = collect(['Desk', 'Sofa', 'Chair']);

\$intersect = \$collection->intersect(['Desk', 'Chair', 'Bookcase']);

\$intersect->all();

// [0 => 'Desk', 2 => 'Chair']``````

#### `isEmpty()`

``````collect([])->isEmpty();

// true``````

#### `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()`

``````\$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()`

``````collect([1, 2, 3, 4])->last(function (\$value, \$key) {
return \$value < 3;
});

// 2``````

``````collect([1, 2, 3, 4])->last();

// 4``````

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

#### `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 = collect([['foo' => 10], ['foo' => 20]])->max('foo');

// 20

\$max = collect([1, 2, 3, 4, 5])->max();

// 5``````

#### `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 = collect([['foo' => 10], ['foo' => 20]])->min('foo');

// 10

\$min = collect([1, 2, 3, 4, 5])->min();

// 1``````

#### `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

#### `pipe()`

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

\$piped = \$collection->pipe(function (\$collection) {
return \$collection->sum();
});

// 6``````

#### `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()`

``````\$collection = collect([1, 2, 3, 4, 5]);

\$collection->pop();

// 5

\$collection->all();

// [1, 2, 3, 4]``````

#### `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()`

``````\$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);

\$collection->pull('name');

// 'Desk'

\$collection->all();

// ['product_id' => 'prod-100']``````

#### `push()`

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

\$collection->push(5);

\$collection->all();

// [1, 2, 3, 4, 5]``````

#### `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``````

``````\$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``````

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

#### `sort()`

``````\$collection = collect([5, 3, 1, 2, 4]);

\$sorted = \$collection->sort();

\$sorted->values()->all();

// [1, 2, 3, 4, 5]``````

{tip} 要排序嵌套数组或对象的集合，见 `sortBy``sortByDesc` 方法。

#### `sortBy()`

``````\$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()`

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

#### `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()`

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

#### `toArray()`

``````\$collection = collect(['name' => 'Desk', 'price' => 200]);

\$collection->toArray();

/*
[
['name' => 'Desk', 'price' => 200],
]
*/``````

{note} `toArray` 也会转换所有内嵌的对象为数组。假如你希望获取原本的底层数组，改用 `all` 方法。

#### `toJson()`

``````\$collection = collect(['name' => 'Desk', 'price' => 200]);

\$collection->toJson();

// '{"name":"Desk", "price":200}'``````

#### `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()`

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

#### `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],
]
*/``````

#### `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],
]
*/``````

#### `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],
]
*/``````

#### `zip()`

`zip` 方法将集合与指定数组相同索引的值合并在一起：

``````\$collection = collect(['Chair', 'Desk']);

\$zipped = \$collection->zip([100, 200]);

\$zipped->all();

// [['Chair', 100], ['Desk', 200]]``````

{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。

《L01 基础入门》

《L03 构架 API 服务器》

1 个点赞 | 0 个回复 | 问答 | 课程版本 5.7

0 个点赞 | 7 个回复 | 问答 | 课程版本 5.5

0 个点赞 | 4 个回复 | 问答 | 课程版本 5.6

0 个点赞 | 3 个回复 | 问答 | 课程版本 5.8

0 个点赞 | 2 个回复 | 问答 | 课程版本 5.8