laravel
5. 深入探讨
集合

介绍

Illuminate\Support\Collection 类为处理数据数组提供了一个流畅、便捷的包装器。例如,查看以下代码。我们将使用 collect 助手从数组创建一个新的集合实例,对每个元素运行 strtoupper 函数,然后删除所有空元素:

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

如您所见,Collection 类允许您链式调用其方法来对基础数组进行流畅的映射和归约。一般来说,集合是不可变的,这意味着每个 Collection 方法都会返回一个全新的 Collection 实例。

创建集合

如上所述,collect 助手为给定的数组返回一个新的 Illuminate\Support\Collection 实例。因此,创建一个集合非常简单:

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

[!NOTE]
Eloquent 查询的结果总是以 Collection 实例的形式返回。

扩展集合

集合是“可宏定义的”,这允许您在运行时向 Collection 类添加额外的方法。Illuminate\Support\Collection 类的 macro 方法接受一个闭包,当您的宏被调用时,该闭包将被执行。宏闭包可以通过 $this 访问集合的其他方法,就好像它是集合类的一个真正方法一样。例如,以下代码向 Collection 类添加了一个 toUpper 方法:

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

Collection::macro('toUpper', function () {
    return $this->map(function (string $value) {
        return Str::upper($value);
    });
});

$collection = collect(['first','second']);

$upper = $collection->toUpper();

// ['FIRST', 'SECOND']

通常,您应该在 服务提供者boot 方法中声明集合宏。

宏参数

如果需要,您可以定义接受其他参数的宏:

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Lang;

Collection::macro('toLocale', function (string $locale) {
    return $this->map(function (string $value) use ($locale) {
        return Lang::get($value, [], $locale);
    });
});

$collection = collect(['first','second']);

$translated = $collection->toLocale('es');

可用方法

在集合文档的大部分剩余内容中,我们将讨论 Collection 类上的每个可用方法。请记住,所有这些方法都可以链式调用,以流畅地操作基础数组。此外,几乎每个方法都会返回一个新的 Collection 实例,以便在必要时保留集合的原始副本:

方法列表

after() {.collection-method.first-collection-method}

after 方法返回给定项之后的项。如果未找到给定项或给定项是最后一项,则返回 null

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

$collection->after(3);

// 4

$collection->after(5);

// null

此方法使用“宽松”比较来搜索给定项,这意味着包含整数值的字符串将被视为与具有相同值的整数相等。要使用“严格”比较,您可以向该方法提供 strict 参数:

collect([2, 4, 6, 8])->after('4', strict: true);

// null

或者,您可以提供自己的闭包来搜索通过给定真值测试的第一个项:

collect([2, 4, 6, 8])->after(function (int $item, int $key) {
    return $item > 5;
});

// 8

all() {.collection-method}

all 方法返回集合所表示的基础数组:

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

// [1, 2, 3]

average() {.collection-method}

avg 方法的别名。

avg() {.collection-method}

avg 方法返回给定键的平均值 (opens in a new tab)

$average = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->avg('foo');

// 20

$average = collect([1, 1, 2, 4])->avg();

// 2

before() {.collection-method}

before 方法与 after 方法相反。它返回给定项之前的项。如果未找到给定项或给定项是第一项,则返回 null

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

$collection->before(3);

// 2

$collection->before(1);

// null

collect([2, 4, 6, 8])->before('4', strict: true);

// null

collect([2, 4, 6, 8])->before(function (int $item, int $key) {
    return $item > 5;
});

// 4

chunk() {.collection-method}

chunk 方法将集合分割为给定大小的多个较小集合:

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

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

$chunks->all();

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

视图 中处理诸如 Bootstrap (opens in a new tab) 之类的网格系统时,此方法特别有用。例如,假设您有一个要在网格中显示的 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

chunkWhile() {.collection-method}

chunkWhile 方法根据给定回调的评估将集合分割为多个较小的集合。传递给闭包的 $chunk 变量可用于检查前一个元素:

$collection = collect(str_split('AABBCCCD'));

$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {
    return $value === $chunk->last();
});

$chunks->all();

// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]

collapse() {.collection-method}

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]

collect() {.collection-method}

collect 方法返回一个新的 Collection 实例,其中包含当前集合中的项:

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

$collectionB = $collectionA->collect();

$collectionB->all();

// [1, 2, 3]

collect 方法主要用于将惰性集合转换为标准的 Collection 实例:

$lazyCollection = LazyCollection::make(function () {
    yield 1;
    yield 2;
    yield 3;
});

$collection = $lazyCollection->collect();

$collection::class;

// 'Illuminate\Support\Collection'

$collection->all();

// [1, 2, 3]

[!NOTE]
当您有一个 Enumerable 实例并且需要一个非惰性集合实例时,collect 方法特别有用。由于 collect()Enumerable 契约的一部分,您可以安全地使用它来获取 Collection 实例。

combine() {.collection-method}

combine 方法将集合的值(作为键)与另一个数组或集合的值相结合:

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

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

$combined->all();

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

concat() {.collection-method}

concat 方法将给定的 array 或集合的值附加到另一个集合的末尾:

$collection = collect(['John Doe']);

$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);

$concatenated->all();

// ['John Doe', 'Jane Doe', 'Johnny Doe']

concat 方法对附加到原始集合上的项的键进行数字重新索引。要在关联集合中保留键,请参阅 merge 方法。

contains() {.collection-method}

contains 方法确定集合是否包含给定项。您可以向 contains 方法传递一个闭包,以确定集合中是否存在与给定真值测试匹配的元素:

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

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

// false

或者,您可以向 `

implode() {.collection-method}

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'

如果您希望格式化正在连接的值,可以向implode方法传递一个闭包:

$collection->implode(function (array $item, int $key) {
    return strtoupper($item['product']);
}, ', ');

// DESK, CHAIR

intersect() {.collection-method}

intersect方法从原始集合中删除不在给定的array或集合中存在的值。结果集合将保留原始集合的键:

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

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

[!NOTE]
当使用Eloquent 集合时,此方法的行为会有所修改。

intersectAssoc() {.collection-method}

intersectAssoc方法将原始集合与另一个集合或array进行比较,返回在所有给定集合中都存在的键/值对:

$collection = collect([
    'color' => 'red',
    'size' => 'M',
    'material' => 'cotton'
]);
 
$intersect = $collection->intersectAssoc([
    'color' => 'blue',
    'size' => 'M',
    'material' => 'polyester'
]);
 
$intersect->all();

// ['size' => 'M']

intersectByKeys() {.collection-method}

intersectByKeys方法从原始集合中删除不在给定的array或集合中存在的键及其对应的值:

$collection = collect([
   'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,
]);
 
$intersect = $collection->intersectByKeys([
   'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,
]);
 
$intersect->all();

// ['type' => 'screen', 'year' => 2009]

isEmpty() {.collection-method}

isEmpty方法如果集合为空,则返回true;否则,返回false

collect([])->isEmpty();

// true

isNotEmpty() {.collection-method}

isNotEmpty方法如果集合不为空,则返回true;否则,返回false

collect([])->isNotEmpty();

// false

join() {.collection-method}

join方法使用一个字符串连接集合的值。使用该方法的第二个参数,您还可以指定如何将最后一个元素附加到字符串中:

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 '); // ''

keyBy() {.collection-method}

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 (array $item, int $key) {
    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-method}

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() {.collection-method}

last方法返回集合中通过给定真值测试的最后一个元素:

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

// 2

您也可以不带参数调用last方法来获取集合中的最后一个元素。如果集合为空,则返回null

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

// 4

lazy() {.collection-method}

lazy方法从底层的项数组中返回一个新的LazyCollection实例:

$lazyCollection = collect([1, 2, 3, 4])->lazy();
 
$lazyCollection::class;

// Illuminate\Support\LazyCollection

$lazyCollection->all();

// [1, 2, 3, 4]

当您需要对包含许多项的大型Collection执行转换时,这特别有用:

$count = $hugeCollection
    ->lazy()
    ->where('country', 'FR')
    ->where('balance', '>', '100')
    ->count();

通过将集合转换为LazyCollection,我们可以避免分配大量的额外内存。尽管原始集合仍然在内存中保留其值,但后续的过滤器不会。因此,在过滤集合的结果时,几乎不会分配额外的内存。

macro() {.collection-method}

静态macro方法允许您在运行时向Collection类添加方法。有关更多信息,请参考关于扩展集合的文档。

make() {.collection-method}

静态make方法创建一个新的集合实例。请参阅创建集合部分。

map() {.collection-method}

map方法遍历集合,并将每个值传递给给定的回调函数。回调函数可以自由地修改项并返回它,从而形成一个修改后的项的新集合:

$collection = collect([1, 2, 3, 4, 5]);
 
$multiplied = $collection->map(function (int $item, int $key) {
    return $item * 2;
});
 
$multiplied->all();

// [2, 4, 6, 8, 10]

[!WARNING]
像大多数其他集合方法一样,map返回一个新的集合实例;它不会修改它所调用的集合。如果您想要转换原始集合,请使用transform方法。

mapInto() {.collection-method}

mapInto()方法遍历集合,通过将值传递到构造函数中创建给定类的新实例:

class Currency
{
    /**
     * 创建一个新的货币实例。
     */
    function __construct(
        public string $code,
    ) {}
}
 
$collection = collect(['USD', 'EUR', 'GBP']);
 
$currencies = $collection->mapInto(Currency::class);
 
$currencies->all();

// [Currency('USD'), Currency('EUR'), Currency('GBP')]

mapSpread() {.collection-method}

mapSpread方法遍历集合的项,将每个嵌套项值传递给给定的闭包。闭包可以自由地修改项并返回它,从而形成一个修改后的项的新集合:

$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
 
$chunks = $collection->chunk(2);
 
$sequence = $chunks->mapSpread(function (int $even, int $odd) {
    return $even + $odd;
});
 
$sequence->all();

// [1, 5, 9, 13, 17]

mapToGroups() {.collection-method}

mapToGroups方法根据给定的闭包对集合的项进行分组。闭包应该返回一个包含单个键/值对的关联数组,从而形成一个分组值的新集合:

$collection = collect([
    [
        'name' => 'John Doe',
        'department' => 'Sales',
    ],
    [
        'name' => 'Jane Doe',
        'department' => 'Sales',
    ],
    [
        'name' => 'Johnny Doe',
        'department' => 'Marketing',
    ]
]);
 
$grouped = $collection->mapToGroups(function (array $item, int $key) {
    return [$item['department'] => $item['name']];
});
 
$grouped->all();

/* [ 'Sales' => ['John Doe', 'Jane Doe'], 'Marketing' => ['Johnny Doe'], ] */

$grouped->get('Sales')->all();

// ['John Doe', 'Jane Doe']

mapWithKeys() {.collection-method}

mapWithKeys方法遍历集合,并将每个值传递给给定的回调函数。回调函数应该返回一个包含单个键/值对的关联数组:

$collection = collect([
    [
        'name' => 'John',
        'department' => 'Sales',
        'email' => 'john@example.com',
    ],
    [
        'name' => 'Jane',
        'department' => 'Marketing',
        'email' => 'jane@example.com',
    ]
]);
 
$keyed = $collection->mapWithKeys(function (array $item, int $key) {
    return [$item['email'] => $item['name']];
});
 
$keyed->all();

/* [ 'john@example.com' => 'John', 'jane@example.com' => 'Jane', ] */

max() {.collection-method}

max方法返回给定键的最大值:

$max = collect([
    ['foo' => 10],
    ['foo' => 20]
])->max('foo');

// 20

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

// 5

median() {.collection-method}

median方法返回给定键的中位数值 (opens in a new tab)

$median = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->median('foo');

// 15

$median = collect([1, 1, 2, 4])->median();

// 1.5

merge() {.collection-method}

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

mergeRecursive() {.collection-method}

mergeRecursive方法递归地将给定的数组或集合与原始集合合并。如果给定项中的字符串键与原始集合中的字符串键匹配,则这些键的值将合并到一个数组中,并递归地进行此操作:

$collection = collect(['product_id' => 1, 'price' => 100]);
 
$merged = $collection->mergeRecursive([
    'product_id' => 2,
    'price' => 200,
    'discount' => false
]);
 
$merged->all();

// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]

min() {.collection-method}

min方法返回给定键的最小值:

$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');

// 10

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

// 1

mode() {.collection-method}

mode方法返回给定键的众数值 (opens in a new tab)

$mode = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->mode('foo');

// [10]

$mode = collect([1, 1, 2, 4])->mode();

// [1]

$mode = collect([1, 1, 2, 2])->mode();

// [1, 2]

multiply() {.collection-method}

multiply方法创建集合中所有项的指定数量的副本:

$users = collect([
    ['name' => 'User #1', 'email' => 'user1@example.com'],
    ['name' => 'User #2', 'email' => 'user2@example.com'],
])->multiply(3);

/* [ ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ] */

nth() {.collection-method}

nth方法创建一个由每隔n个元素组成的新集合:

$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);
 
$collection->nth(4);

// ['a', 'e']

您可以可选地将起始偏移量作为第二个参数传递:

$collection->nth(4, 1);

// ['b', 'f']

only() {.collection-method}

sortByDesc() {.collection-method}

此方法与 sortBy 方法具有相同的签名,但会以相反的顺序对集合进行排序。

sortDesc() {.collection-method}

此方法将以与 sort 方法相反的顺序对集合进行排序:

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

$sorted = $collection->sortDesc();

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

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

sort 不同,您不能向 sortDesc 传递闭包。相反,您应该使用 sort 方法并反转您的比较。

sortKeys() {.collection-method}

sortKeys 方法按基础关联数组的键对集合进行排序:

$collection = collect([
    'id' => 22345,
    'first' => 'John',
    'last' => 'Doe',
]);

$sorted = $collection->sortKeys();

$sorted->all();

/*
    [
        'first' => 'John',
        'id' => 22345,
        'last' => 'Doe',
    ]
*/

sortKeysDesc() {.collection-method}

此方法与 sortKeys 方法具有相同的签名,但会以相反的顺序对集合进行排序。

sortKeysUsing() {.collection-method}

sortKeysUsing 方法使用回调函数按基础关联数组的键对集合进行排序:

$collection = collect([
    'ID' => 22345,
    'first' => 'John',
    'last' => 'Doe',
]);

$sorted = $collection->sortKeysUsing('strnatcasecmp');

$sorted->all();

/*
    [
        'first' => 'John',
        'ID' => 22345,
        'last' => 'Doe',
    ]
*/

回调必须是一个比较函数,它返回一个小于、等于或大于零的整数。有关更多信息,请参考 PHP 文档中关于 uksort (opens in a new tab) 的内容,这是 sortKeysUsing 方法在内部使用的 PHP 函数。

splice() {.collection-method}

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() {.collection-method}

split 方法将集合拆分为给定数量的组:

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

$groups = $collection->split(3);

$groups->all();

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

splitIn() {.collection-method}

splitIn 方法将集合拆分为给定数量的组,在分配剩余部分到最后一组之前完全填充非终端组:

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

$groups = $collection->splitIn(3);

$groups->all();

// [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]

sum() {.collection-method}

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 (array $product) {
    return count($product['colors']);
});

// 6

take() {.collection-method}

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]

takeUntil() {.collection-method}

takeUntil 方法返回集合中的项,直到给定的回调函数返回 true

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

$subset = $collection->takeUntil(function (int $item) {
    return $item >= 3;
});

$subset->all();

// [1, 2]

您也可以向 takeUntil 方法传递一个简单值,以获取直到找到给定值的项:

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

$subset = $collection->takeUntil(3);

$subset->all();

// [1, 2]

[!WARNING]
如果未找到给定值或回调函数从未返回 true,则 takeUntil 方法将返回集合中的所有项。

takeWhile() {.collection-method}

takeWhile 方法返回集合中的项,直到给定的回调函数返回 false

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

$subset = $collection->takeWhile(function (int $item) {
    return $item < 3;
});

$subset->all();

// [1, 2]

[!WARNING]
如果回调函数从未返回 false,则 takeWhile 方法将返回集合中的所有项。

tap() {.collection-method}

tap 方法将集合传递给给定的回调函数,允许您在特定点“接入”集合,并在不影响集合本身的情况下对项进行操作。然后,tap 方法将集合返回:

collect([2, 4, 3, 1, 5])
    ->sort()
    ->tap(function (Collection $collection) {
        Log::debug('Values after sorting', $collection->values()->all());
    })
    ->shift();

// 1

times() {.collection-method}

静态 times 方法通过调用给定的闭包指定次数来创建一个新集合:

$collection = Collection::times(10, function (int $number) {
    return $number * 9;
});

$collection->all();

// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]

toArray() {.collection-method}

toArray 方法将集合转换为普通的 PHP array。如果集合的值是 Eloquent 模型,这些模型也将被转换为数组:

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

$collection->toArray();

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

[!WARNING]
toArray 还会将集合中所有作为 Arrayable 实例的嵌套对象转换为数组。如果您想要获取集合底层的原始数组,请使用 all 方法代替。

toJson() {.collection-method}

toJson 方法将集合转换为 JSON 序列化字符串:

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

$collection->toJson();

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

transform() {.collection-method}

transform 方法遍历集合,并使用集合中的每个项调用给定的回调函数。集合中的项将被回调函数返回的值替换:

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

$collection->transform(function (int $item, int $key) {
    return $item * 2;
});

$collection->all();

// [2, 4, 6, 8, 10]

[!WARNING]
与大多数其他集合方法不同,transform 会修改集合本身。如果您希望创建一个新的集合,而不是修改原始集合,请使用 map 方法。

undot() {.collection-method}

undot 方法将使用“点”符号的单维集合扩展为多维集合:

$person = collect([
    'name.first_name' => 'Marie',
    'name.last_name' => 'Valentine',
    'address.line_1' => '2992 Eagle Drive',
    'address.line_2' => '',
    'address.suburb' => 'Detroit',
    'address.state' => 'MI',
    'address.postcode' => '48219'
]);

$person = $person->undot();

$person->toArray();

/*
    [
        "name" => [
            "first_name" => "Marie",
            "last_name" => "Valentine",
        ],
        "address" => [
            "line_1" => "2992 Eagle Drive",
            "line_2" => "",
            "suburb" => "Detroit",
            "state" => "MI",
            "postcode" => "48219",
        ],
    ]
*/

union() {.collection-method}

union 方法将给定的数组添加到集合中。如果给定的数组包含已经在原始集合中的键,则原始集合的值将被优先考虑:

$collection = collect([1 => ['a'], 2 => ['b']]);

$union = $collection->union([3 => ['c'], 1 => ['d']]);

$union->all();

// [1 => ['a'], 2 => ['b'], 3 => ['c']]

unique() {.collection-method}

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 方法传递自己的闭包,以指定哪个值应确定项的唯一性:

$unique = $collection->unique(function (array $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 方法进行“严格”比较来过滤。

[!NOTE]
当使用 Eloquent Collections 时,此方法的行为会有所修改。

uniqueStrict() {.collection-method}

此方法与 unique 方法具有相同的签名;然而,所有值都使用“严格”比较进行比较。

unless() {.collection-method}

unless 方法将执行给定的回调函数,除非传递给该方法的第一个参数的计算结果为 true

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

$collection->unless(true, function (Collection $collection) {
    return $collection->push(4);
});

$collection->unless(false, function (Collection $collection) {
    return $collection->push(5);
});

$collection->all();

// [1, 2, 3, 5]

可以向 unless 方法传递第二个回调函数。当传递给 unless 方法的第一个参数的计算结果为 true 时,将执行第二个回调函数:

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

$collection->unless(true, function (Collection $collection) {
    return $collection->push(4);
}, function (Collection $collection) {
    return $collection->push(5);
});

$collection->all();

// [1, 2, 3, 5]

对于 unless 的逆操作,请参阅 when 方法。

unlessEmpty() {.collection-method}

whenNotEmpty 方法的别名。

unlessNotEmpty() {.collection-method}

whenEmpty 方法的别名。

unwrap() {.collection-method}

静态 unwrap 方法在适用时从给定值中返回集合的底层项:

Collection::unwrap(collect('John Doe'));

// ['John Doe']

Collection::unwrap(['John Doe']);

// ['John Doe']

Collection::unwrap('John Doe');

// 'John Doe'

value() {.collection-method}

value 方法从集合的第一个元素中检索给定的值:

$collection = collect