此 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]);[!注意]
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
all
average
avg
before
chunk
chunkWhile
collapse
collapseWithKeys
collect
combine
concat
contains
containsOneItem
containsStrict
count
countBy
crossJoin
dd
diff
diffAssoc
diffAssocUsing
diffKeys
doesntContain
doesntContainStrict
dot
dump
duplicates
duplicatesStrict
each
eachSpread
ensure
every
except
filter
first
firstOrFail
firstWhere
flatMap
flatten
flip
forget
forPage
fromJson
get
groupBy
has
hasAny
implode
intersect
intersectUsing
intersectAssoc
intersectAssocUsing
intersectByKeys
isEmpty
isNotEmpty
join
keyBy
keys
last
lazy
macro
make
map
mapInto
mapSpread
mapToGroups
mapWithKeys
max
median
merge
mergeRecursive
min
mode
multiply
nth
only
pad
partition
percentage
pipe
pipeInto
pipeThrough
pluck
pop
prepend
pull
push
put
random
range
reduce
reduceSpread
reject
replace
replaceRecursive
reverse
search
select
shift
shuffle
skip
skipUntil
skipWhile
slice
sliding
sole
some
sort
sortBy
sortByDesc
sortDesc
sortKeys
sortKeysDesc
sortKeysUsing
splice
split
splitIn
sum
take
takeUntil
takeWhile
tap
times
toArray
toJson
toPrettyJson
transform
undot
union
unique
uniqueStrict
unless
unlessEmpty
unlessNotEmpty
unwrap
value
values
when
whenEmpty
whenNotEmpty
where
whereStrict
whereBetween
whereIn
whereInStrict
whereInstanceOf
whereNotBetween
whereNotIn
whereNotInStrict
whereNotNull
whereNull
wrap
zip
after()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 方法返回由集合表示的底层数组:
collect([1, 2, 3])->all();
// [1, 2, 3]average()[avg](#method-avg) 方法的别名。
avg()该 avg 方法返回给定键的 平均值:
$average = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->avg('foo');
// 20
$average = collect([1, 1, 2, 4])->avg();
// 2before()before 方法与 [after](#method-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;
});
// 4chunk()该 chunk 方法将集合拆分为给定大小的多个较小集合:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
// [[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>
@endforeachchunkWhile()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()该 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]collapseWithKeys()collapseWithKeys 方法将数组或集合的集合扁平化为单个集合,同时保持原始键不变。如果该集合已经扁平化,它将返回一个空集合:
$collection = collect([
['first' => collect([1, 2, 3])],
['second' => [4, 5, 6]],
['third' => collect([7, 8, 9])]
]);
$collapsed = $collection->collapseWithKeys();
$collapsed->all();
// [
// 'first' => [1, 2, 3],
// 'second' => [4, 5, 6],
// 'third' => [7, 8, 9],
// ]收集()此 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]
collect方法特别有用,当你有一个Enumerable实例并需要一个非惰性集合实例时。由于collect()是Enumerable契约的一部分,你可以安全地使用它来获取一个Collection实例。
合并()该 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']concat 方法会对连接到原始集合上的项的键进行数字重新索引。 要保留关联集合中的键, 请参阅 merge 方法。
contains()该 contains 方法判断集合是否包含给定项。你可以传递一个闭包给 contains 方法,来判断集合中是否存在匹配给定真值测试的元素:
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function (int $value, int $key) {
return $value > 5;
});
// false或者,你可以向 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 方法在检查项值时使用“宽松”比较,这意味着一个具有整数值的字符串将被视为与一个相同值的整数相等。使用 [containsStrict](#method-containsstrict) 方法进行“严格”比较筛选。
对于 contains 的逆操作,请参阅 不包含 方法。
containsOneItem()该 containsOneItem 方法用于确定集合中是否包含单个项目:
collect([])->containsOneItem();
// false
collect(['1'])->containsOneItem();
// true
collect(['1', '2'])->containsOneItem();
// false
collect([1, 2, 3])->containsOneItem(fn (int $item) => $item === 2);
// truecontainsStrict()这个方法具有与 contains 方法相同的签名; 然而,所有值都使用"严格"比较进行比较。
[!注意]
当使用 Eloquent 集合 时,此方法的行为会发生改变。
count()count 方法返回集合中的项目总数:
$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4countBy()该 countBy 方法统计集合中值的出现次数。默认情况下,该方法统计每个元素的出现次数,从而允许你统计集合中某些“类型”的元素:
$collection = collect([1, 2, 2, 2, 3]);
$counted = $collection->countBy();
$counted->all();
// [1 => 1, 2 => 3, 3 => 1]您可以传入一个闭包到 countBy 方法,以根据自定义值统计所有项:
$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']);
$counted = $collection->countBy(function (string $email) {
return substr(strrchr($email, '@'), 1);
});
$counted->all();
// ['gmail.com' => 2, 'yahoo.com' => 1]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();
/*
array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
*/如果你不想停止执行脚本,请使用 转储 方法。
diff()diff 方法根据值比较该集合与另一个集合或一个普通的 PHP array。此方法将返回那些在原始集合中但不存在于给定集合中的值:
$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5][!注意]
此方法的行为在使用 Eloquent 集合 时会发生改变。
diffAssoc()diffAssoc 方法根据键和值将集合与另一个集合或普通的 PHP array 进行比较。此方法将返回原始集合中不存在于给定集合中的键/值对:
$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]diffAssocUsing()与 diffAssoc 不同的是,diffAssocUsing 接受一个用户提供的回调函数用于索引比较:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6,
]);
$diff = $collection->diffAssocUsing([
'Color' => 'yellow',
'Type' => 'fruit',
'Remain' => 3,
], 'strnatcasecmp');
$diff->all();
// ['color' => 'orange', 'remain' => 6]回调函数必须是一个比较函数,它返回一个小于、等于或大于零的整数。欲了解更多信息,请参考PHP关于array_diff_uassoc的文档,它是 diffAssocUsing 方法在内部利用的PHP函数。
比较键()该 diffKeys 方法基于其键将集合与另一个集合或一个普通的 PHP array 进行比较。此方法将返回原始集合中不存在于给定集合中的键/值对:
$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]不包含()该 doesntContain 方法用于判断集合中是否不包含给定项。您可以向 doesntContain 方法传入一个闭包,以确定集合中是否不存在满足给定真值测试的元素:
$collection = collect([1, 2, 3, 4, 5]);
$collection->doesntContain(function (int $value, int $key) {
return $value < 5;
});
// false或者,你可以传递一个字符串给 doesntContain 方法来判断集合是否不包含给定的项值:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->doesntContain('Table');
// true
$collection->doesntContain('Desk');
// false您也可以传递一个键/值对给 doesntContain 方法,它将确定给定的对是否不存在于集合中:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->doesntContain('product', 'Bookcase');
// truedoesntContain 方法在检查项值时使用“宽松”比较,这意味着一个带有整数值的字符串将被视为与一个相同值的整数相等。
严格不包含()此方法具有与 doesntContain 方法相同的签名;然而,所有值都使用“严格”比较进行比较。
dot()该dot方法 展平 一个多维集合 为 一个单层集合 其 使用 “点” 表示法 来 指示 深度:
$collection = collect(['products' => ['desk' => ['price' => 100]]]);
$flattened = $collection->dot();
$flattened->all();
// ['products.desk.price' => 100]dump()该 dump 方法转储集合中的项:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
*/如果你想在转储集合后停止执行脚本,请使用 dd 方法代替。
duplicates()该 duplicates 方法从集合中检索并返回重复值:
$collection = collect(['a', 'b', 'a', 'c', 'b']);
$collection->duplicates();
// [2 => 'a', 4 => 'b']如果集合包含数组或对象,您可以传递您希望检查重复值的属性的键:
$employees = collect([
['email' => 'abigail@example.com', 'position' => 'Developer'],
['email' => 'james@example.com', 'position' => 'Designer'],
['email' => 'victoria@example.com', 'position' => 'Developer'],
]);
$employees->duplicates('position');
// [2 => 'Developer']duplicatesStrict()此方法与 duplicates 方法具有相同的签名;然而,所有值都使用"严格"比较进行比较。
each()“each”方法遍历集合中的项目,并将每个项目传递给闭包:
$collection = collect([1, 2, 3, 4]);
$collection->each(function (int $item, int $key) {
// ...
});如果您想停止遍历这些项目,您可以从您的闭包中返回 false:
$collection->each(function (int $item, int $key) {
if (/* condition */) {
return false;
}
});eachSpread()eachSpread 方法遍历集合中的项,并将每个嵌套项的值传递给指定的回调函数:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);
$collection->eachSpread(function (string $name, int $age) {
// ...
});您可以通过从回调中返回 假 停止遍历这些项:
$collection->eachSpread(function (string $name, int $age) {
return false;
});ensure()该 ensure 方法可用于验证集合中的所有元素是否为给定类型或类型列表。否则,将抛出 UnexpectedValueException 异常:
return $collection->ensure(User::class);
return $collection->ensure([User::class, Customer::class]);原始类型,例如string, int, float, bool, 以及array也可以指定:
return $collection->ensure('int');[!警告]
ensure方法不保证之后不会向集合中添加不同类型的元素。
every()every 方法可用于验证集合中的所有元素都通过给定的真值测试:
collect([1, 2, 3, 4])->every(function (int $value, int $key) {
return $value > 2;
});
// false如果集合为空,则 every 方法将返回 true:
$collection = collect([]);
$collection->every(function (int $value, int $key) {
return $value > 2;
});
// true排除()except 方法返回集合中除具有指定键的项之外的所有项:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);
$filtered = $collection->except(['price', 'discount']);
$filtered->all();
// ['product_id' => 1]对于 except 的反向操作,请参阅 only 方法。
[!注意]
当使用 Eloquent 集合 时,此方法的行为会发生改变。
filter()该filter方法使用给定的回调函数过滤集合,只保留通过给定真值测试的项:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function (int $value, int $key) {
return $value > 2;
});
$filtered->all();
// [3, 4]如果未提供回调,集合中所有等价于 false 的条目将被移除:
$collection = collect([1, 2, 3, null, false, '', 0, []]);
$collection->filter()->all();
// [1, 2, 3]对于 filter 的逆操作,请参阅 拒绝 方法。
first()该 first 方法返回集合中第一个通过给定真值测试的元素:
collect([1, 2, 3, 4])->first(function (int $value, int $key) {
return $value > 2;
});
// 3你也可以不带任何参数调用 first 方法,以获取集合中的第一个元素。如果集合为空,则返回 null:
collect([1, 2, 3, 4])->first();
// 1firstOrFail()firstOrFail 方法等同于 first 方法;然而,如果没有找到结果,将抛出 Illuminate\Support\ItemNotFoundException 异常:
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {
return $value > 5;
});
// Throws ItemNotFoundException...你也可以调用 firstOrFail 方法且不带任何参数,以获取集合中的第一个元素。如果集合为空,则会抛出 Illuminate\Support\ItemNotFoundException 异常:
collect([])->firstOrFail();
// Throws ItemNotFoundException...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](#method-where) 方法,你可以传递一个参数给 firstWhere 方法。在这种情况下,firstWhere 方法将返回第一个项,其给定项键的值为“真值”:
$collection->firstWhere('age');
// ['name' => 'Linda', 'age' => 14]flatMap()flatMap 方法遍历集合,并将每个值传递给给定的闭包。该闭包可以自由地修改项并将其返回,从而形成一个由修改后的项组成的新集合。然后,该数组会按一层进行扁平化处理:
$collection = collect([
['name' => 'Sally'],
['school' => 'Arkansas'],
['age' => 28]
]);
$flattened = $collection->flatMap(function (array $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'];如有必要,您可以向 flatten 方法传入一个“深度”参数:
$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']);
// Forget a single key...
$collection->forget('name');
// ['framework' => 'Laravel']
// Forget multiple keys...
$collection->forget(['name', 'framework']);
// [][!WARNING]
与大多数其他集合方法不同,forget不会返回一个新的修改过的集合;它会修改并返回对其进行操作的集合。
forPage()该 forPage 方法返回一个新集合包含将出现在给定页码上的项。该方法接受页码作为其第一个参数以及每页显示的项数作为其第二个参数:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();
// [4, 5, 6]fromJson()静态的 fromJson 方法通过使用 json_decode PHP 函数解码给定的 JSON 字符串,创建一个新的集合实例:
use Illuminate\Support\Collection;
$json = json_encode([
'name' => 'Taylor Otwell',
'role' => 'Developer',
'status' => 'Active',
]);
$collection = Collection::fromJson($json);get()get 方法返回给定键的值。如果键不存在,则返回 null:
$collection = collect(['name' => 'Taylor', 'framework' => 'Laravel']);
$value = $collection->get('name');
// Taylor你可以选择性地传递一个默认值作为第二个参数:
$collection = collect(['name' => 'Taylor', 'framework' => 'Laravel']);
$value = $collection->get('age', 34);
// 34你甚至可以将回调作为方法的默认值传递。如果指定的键不存在,将返回回调的结果:
$collection->get('email', function () {
return 'taylor@example.com';
});
// taylor@example.comgroupBy()该 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->all();
/*
[
'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 (array $item, int $key) {
return substr($item['account_id'], -3);
});
$grouped->all();
/*
[
'x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/多个分组条件可以作为数组传递。每个数组元素将应用于多维数组中的相应层级:
$data = new Collection([
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
]);
$result = $data->groupBy(['skill', function (array $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']);
// falsehasAny()hasAny 方法确定给定键中的任何一个是否存在于集合中:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->hasAny(['product', 'price']);
// true
$collection->hasAny(['name', 'price']);
// falseimplode()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 = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair'][!NOTE]
此方法的行为在使用Eloquent 集合时会被修改.
intersectUsing()intersectUsing 方法会从原始集合中移除任何不在给定数组或集合中的值,使用自定义回调来比较这些值。结果集合将保留原始集合的键:
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersectUsing(['desk', 'chair', 'bookcase'], function (string $a, string $b) {
return strcasecmp($a, $b);
});
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']intersectAssoc()intersectAssoc 方法将原始集合与另一个集合或数组进行比较,返回所有给定集合中都存在的键值对:
$collection = collect([
'color' => 'red',
'size' => 'M',
'material' => 'cotton'
]);
$intersect = $collection->intersectAssoc([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester'
]);
$intersect->all();
// ['size' => 'M']intersectAssocUsing()intersectAssocUsing 方法将原始集合与另一个集合或数组进行比较,返回两者都存在的键/值对,并使用自定义比较回调来确定键和值的相等性:
$collection = collect([
'color' => 'red',
'Size' => 'M',
'material' => 'cotton',
]);
$intersect = $collection->intersectAssocUsing([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester',
], function (string $a, string $b) {
return strcasecmp($a, $b);
});
$intersect->all();
// ['Size' => 'M']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();
// trueisNotEmpty()isNotEmpty 方法在集合不为空时返回 true;否则,返回 false:
collect([])->isNotEmpty();
// false连接()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()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()该 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 (int $value, int $key) {
return $value < 3;
});
// 2你也可以调用不带任何参数的 last 方法,来获取集合中的最后一个元素。如果集合为空,null 将被返回:
collect([1, 2, 3, 4])->last();
// 4lazy()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()静态的 macro 方法允许你在运行时向 Collection 类添加方法。请查阅关于 扩展集合 的文档以了解更多信息。
make()静态 make 方法创建一个新的集合实例。请参阅 创建集合 部分。
use Illuminate\Support\Collection;
$collection = Collection::make([1, 2, 3]);map()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()该 mapInto() 方法遍历集合,通过将值传入构造函数,创建给定类的新实例:
class Currency
{
/**
* Create a new currency instance.
*/
function __construct(
public string $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 (int $even, int $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 (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()该 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()The max method returns the maximum value of a given key:
$max = collect([
['foo' => 10],
['foo' => 20]
])->max('foo');
// 20
$max = collect([1, 2, 3, 4, 5])->max();
// 5中位数()该 median 方法返回给定键的中位数:
$median = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->median('foo');
// 15
$median = collect([1, 1, 2, 4])->median();
// 1.5merge()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()该 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()The min method returns the minimum value of a given key:
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1mode()该 mode 方法返回给定键的 众数值:
$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 方法创建集合中所有项的指定数量的副本:
$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()该 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 方法。
[!NOTE]
当使用 Eloquent 集合 时,此方法的行为会发生改变.
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 数组解构结合使用以分离通过给定真值测试的元素和未通过的元素:
$collection = collect([1, 2, 3, 4, 5, 6]);
[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {
return $i < 3;
});
$underThree->all();
// [1, 2]
$equalOrAboveThree->all();
// [3, 4, 5, 6][!NOTE]
此方法在与 Eloquent 集合 交互时,其行为会发生修改。
percentage()该 percentage 方法可用于快速确定集合中通过给定真值测试的项目的百分比:
$collection = collect([1, 1, 2, 2, 2, 3]);
$percentage = $collection->percentage(fn (int $value) => $value === 1);
// 33.33默认情况下,百分比将四舍五入到两位小数。但是,您可以通过向该方法提供第二个参数来自定义此行为:
$percentage = $collection->percentage(fn (int $value) => $value === 1, precision: 3);
// 33.333pipe()pipe 方法将集合传递给给定的闭包,并返回执行闭包的结果:
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function (Collection $collection) {
return $collection->sum();
});
// 6导入管道()pipeInto 方法创建给定类的新实例,并将集合传递给构造函数:
class ResourceCollection
{
/**
* Create a new ResourceCollection instance.
*/
public function __construct(
public Collection $collection,
) {}
}
$collection = collect([1, 2, 3]);
$resource = $collection->pipeInto(ResourceCollection::class);
$resource->collection->all();
// [1, 2, 3]管道传输()pipeThrough 方法将集合传递给给定的闭包数组,并返回已执行闭包的结果:
use Illuminate\Support\Collection;
$collection = collect([1, 2, 3]);
$result = $collection->pipeThrough([
function (Collection $collection) {
return $collection->merge([4, 5]);
},
function (Collection $collection) {
return $collection->sum();
},
]);
// 15pluck()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']该 pluck 方法也支持使用“点”表示法检索嵌套值:
$collection = collect([
[
'name' => 'Laracon',
'speakers' => [
'first_day' => ['Rosa', 'Judith'],
],
],
[
'name' => 'VueConf',
'speakers' => [
'first_day' => ['Abigail', 'Joey'],
],
],
]);
$plucked = $collection->pluck('speakers.first_day');
$plucked->all();
// [['Rosa', 'Judith'], ['Abigail', 'Joey']]如果存在重复键,最后一个匹配元素将被插入到提取的集合中:
$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 方法移除并返回集合中的最后一个项目。如果集合为空,将返回 null:
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop();
// 5
$collection->all();
// [1, 2, 3, 4]你可以向 pop 方法传递一个整数,以移除并返回集合末尾的多个项:
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop(3);
// collect([5, 4, 3])
$collection->all();
// [1, 2]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]您也可以提供多个项,以追加到集合的末尾:
$collection = collect([1, 2, 3, 4]);
$collection->push(5, 6, 7);
$collection->all();
// [1, 2, 3, 4, 5, 6, 7]这 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)如果集合实例的项数少于请求的数量,random 方法将抛出 InvalidArgumentException。
random 方法也接受一个闭包,该闭包将接收当前的集合实例:
use Illuminate\Support\Collection;
$random = $collection->random(fn (Collection $items) => min(10, count($items)));
$random->all();
// [1, 2, 3, 4, 5] - (retrieved randomly)range()range 方法返回一个包含指定范围内整数的集合:
$collection = collect()->range(3, 6);
$collection->all();
// [3, 4, 5, 6]归约()该 reduce 方法将集合归约为单个值,并将每次迭代的结果传入下一次迭代中:
$collection = collect([1, 2, 3]);
$total = $collection->reduce(function (?int $carry, int $item) {
return $carry + $item;
});
// 6$carry 在第一次迭代时的值为 null; 但是,您可以通过向 reduce 传递第二个参数来指定其初始值:
$collection->reduce(function (int $carry, int $item) {
return $carry + $item;
}, 4);
// 10该 reduce 方法也传递数组键给给定的回调:
$collection = collect([
'usd' => 1400,
'gbp' => 1200,
'eur' => 1000,
]);
$ratio = [
'usd' => 1,
'gbp' => 1.37,
'eur' => 1.22,
];
$collection->reduce(function (int $carry, int $value, string $key) use ($ratio) {
return $carry + ($value * $ratio[$key]);
}, 0);
// 4264reduceSpread()reduceSpread 方法将集合缩减为一个值数组,将每次迭代的结果传递给后续迭代。此方法与 reduce 方法类似;但是,它可以接受多个初始值:
[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
->get()
->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {
if ($creditsRemaining >= $image->creditsRequired()) {
$batch->push($image);
$creditsRemaining -= $image->creditsRequired();
}
return [$creditsRemaining, $batch];
}, $creditsAvailable, collect());reject()reject 方法使用给定的闭包过滤集合。如果该项应从结果集合中移除,则该闭包应返回 true:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function (int $value, int $key) {
return $value > 2;
});
$filtered->all();
// [1, 2]对于 reject 方法的逆操作,请参阅 filter 方法。
替换()replace 方法的行为类似于 merge;然而,除了覆盖具有字符串键的匹配项之外,replace 方法还将覆盖集合中具有匹配数字键的项:
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']replaceRecursive()replaceRecursive 方法的行为类似于 replace, 但它会递归进入数组并对内部值应用相同的替换过程:
$collection = collect([
'Taylor',
'Abigail',
[
'James',
'Victoria',
'Finn'
]
]);
$replaced = $collection->replaceRecursive([
'Charlie',
2 => [1 => 'King']
]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]反转()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 作为第二个参数传递给该方法:
collect([2, 4, 6, 8])->search('4', strict: true);
// false另外,你可以提供自己的闭包,以搜索通过给定真值测试的第一个项:
collect([2, 4, 6, 8])->search(function (int $item, int $key) {
return $item > 5;
});
// 2该 select 方法从集合中选定给定键,类似于 SQL SELECT 语句:
$users = collect([
['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'],
['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],
]);
$users->select(['name', 'role']);
/*
[
['name' => 'Taylor Otwell', 'role' => 'Developer'],
['name' => 'Victoria Faith', 'role' => 'Researcher'],
],
*/shift()该 shift 方法从集合中移除并返回第一个项目:
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift();
// 1
$collection->all();
// [2, 3, 4, 5]你可以传递一个整数给 shift 方法,以从集合的开头移除并返回多个项目:
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift(3);
// collect([1, 2, 3])
$collection->all();
// [4, 5]shuffle()该 shuffle 方法随机打乱集合中的项:
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (generated randomly)skip()skip 方法返回一个新集合,其中移除了从集合开头指定数量的元素:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$collection = $collection->skip(4);
$collection->all();
// [5, 6, 7, 8, 9, 10]skipUntil()skipUntil 方法在给定的回调返回 false 期间跳过集合中的项目. 一旦回调返回 true 集合中所有剩余的项目都将作为一个新集合返回:`
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(function (int $item) {
return $item >= 3;
});
$subset->all();
// [3, 4]您也可以传递一个简单值到 skipUntil 方法,以跳过所有项直到找到给定值:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(3);
$subset->all();
// [3, 4][!WARNING]
如果未找到给定值,或者回调函数从未返回true,则skipUntil方法将返回一个空集合。
skipWhile()此 skipWhile 方法会跳过集合中的项,只要给定的回调函数返回 true。一旦回调函数返回 false,集合中所有剩余的项都将作为一个新集合返回:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipWhile(function (int $item) {
return $item <= 3;
});
$subset->all();
// [4][!WARNING]
如果回调从不返回false,则skipWhile方法将返回一个空集合。
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]返回的切片默认情况下将保留键。如果您不希望保留原始键,您可以使用 值 方法对其进行重新索引。
sliding()该 sliding 方法返回一个新的分块集合,表示集合中项目的“滑动窗口”视图:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(2);
$chunks->toArray();
// [[1, 2], [2, 3], [3, 4], [4, 5]]这在与 eachSpread 方法结合使用时特别有用:
$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) {
$current->total = $previous->total + $current->amount;
});你可以可选地传递第二个 'step' 值,它决定了每个数据块中第一个项之间的距离:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(3, step: 2);
$chunks->toArray();
// [[1, 2, 3], [3, 4, 5]]sole()sole 方法返回集合中通过给定真值测试的第一个元素,但前提是该真值测试仅匹配一个元素:
collect([1, 2, 3, 4])->sole(function (int $value, int $key) {
return $value === 2;
});
// 2你也可以传递一个键值对给 sole 方法,它将返回集合中匹配给定对的第一个元素,但仅限于只有一个元素匹配时:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->sole('product', 'Chair');
// ['product' => 'Chair', 'price' => 100]或者,你也可以调用不带任何参数的 sole 方法以便在集合中只有一个元素时获取集合中的第一个元素:
$collection = collect([
['product' => 'Desk', 'price' => 200],
]);
$collection->sole();
// ['product' => 'Desk', 'price' => 200]如果集合中没有应该由 sole 方法返回的元素,将会抛出 \Illuminate\Collections\ItemNotFoundException 异常。 如果有多个应该被返回的元素,将会抛出 \Illuminate\Collections\MultipleItemsFoundException 异常。
some()包含 方法的别名.
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],
]
*/sortBy 方法接受 排序标志 作为其第二个参数:
$collection = collect([
['title' => 'Item 1'],
['title' => 'Item 12'],
['title' => 'Item 3'],
]);
$sorted = $collection->sortBy('title', SORT_NATURAL);
$sorted->values()->all();
/*
[
['title' => 'Item 1'],
['title' => 'Item 3'],
['title' => 'Item 12'],
]
*/或者,您可以传入您自己的闭包来决定如何对集合的值进行排序:
$collection = collect([
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$sorted = $collection->sortBy(function (array $product, int $key) {
return count($product['colors']);
});
$sorted->values()->all();
/*
[
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]
*/如果您希望按多个属性对集合进行排序,您可以向 sortBy 方法传递一个排序操作数组。每个排序操作都应该是一个数组,包含您希望排序的属性以及所需排序的方向:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
['name', 'asc'],
['age', 'desc'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/当通过多个属性对集合进行排序时,您也可以提供定义每个排序操作的闭包:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
fn (array $a, array $b) => $a['name'] <=> $b['name'],
fn (array $a, array $b) => $b['age'] <=> $a['age'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/这个方法与 sortBy 方法的签名相同,但会以相反的顺序对集合进行排序。
sortDesc()此方法将以与 排序 方法相反的顺序对集合进行排序:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sortDesc();
$sorted->values()->all();
// [5, 4, 3, 2, 1]不同于 sort,您不能传递一个闭包给 sortDesc。相反,您应该使用 [sort](#method-sort) 方法并反转您的比较逻辑。
排序键()该 sortKeys 方法根据底层关联数组的键对集合进行排序:
$collection = collect([
'id' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeys();
$sorted->all();
/*
[
'first' => 'John',
'id' => 22345,
'last' => 'Doe',
]
*/键降序排序()此方法具有与 sortKeys 方法相同的签名,但将以相反的顺序对集合进行排序。
使用键排序()sortKeysUsing 方法使用回调函数对底层关联数组的键对集合进行排序:
$collection = collect([
'ID' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeysUsing('strnatcasecmp');
$sorted->all();
/*
[
'first' => 'John',
'ID' => 22345,
'last' => 'Doe',
]
*/回调必须是一个比较函数,它返回一个小于、等于或大于零的整数。更多信息,请参阅 PHP 关于 uksort 的文档,它是 sortKeysUsing 方法内部调用的 PHP 函数。
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->all();
// [[1, 2], [3, 4], [5]]splitIn()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 方法返回集合中所有项的总和:
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 = 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 方法返回集合中的项目,直到给定的回调返回 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()该 takeWhile 方法返回集合中的项直到给定的回调函数返回 false:`
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeWhile(function (int $item) {
return $item < 3;
});
$subset->all();
// [1, 2][!警告]
如果回调函数从不返回false,那么takeWhile方法将返回集合中的所有项。
tap()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 = Collection::times(10, function (int $number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]转为数组()toArray 方法将集合转换成一个普通的 PHP array。如果集合的值是 Eloquent 模型,这些模型也将被转换成数组:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/[!WARNING]
toArray也会将集合中所有作为Arrayable实例的嵌套对象转换为数组。如果你想获取集合底层的原始数组,请改用 all 方法。
toJson()该 toJson 方法将集合转换为 JSON 序列化的字符串:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toJson();
// '{"name":"Desk", "price":200}'toPrettyJson()toPrettyJson 方法使用 JSON_PRETTY_PRINT 选项将集合转换为格式化的 JSON 字符串:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toPrettyJson();转换()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()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()union 方法将给定数组添加到集合中。如果给定数组包含已存在于原始集合中的键,则优先保留原始集合的值:
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['d']]);
$union->all();
// [1 => ['a'], 2 => ['b'], 3 => ['c']]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 集合 时会发生改变。
uniqueStrict()此方法具有与 unique 方法相同的签名;然而,所有值都使用“严格”比较进行比较。
unless()此 unless 方法将执行指定的回调,除非传递给该方法的第一个参数求值为 true。集合实例和传递给 unless 方法的第一个参数将提供给闭包:
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection, bool $value) {
return $collection->push(4);
});
$collection->unless(false, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]第二个回调可以传递给 unless 方法。当传递给 unless 方法的第一个参数评估结果为 true 时,第二个回调将会执行:
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection, bool $value) {
return $collection->push(4);
}, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]对于 unless 的反义,请参阅 when 方法。
除非为空()whenNotEmpty 方法的别名。
unlessNotEmpty()whenEmpty 方法的别名。
解包()静态 unwrap 方法在适用时,从给定值中返回集合的底层项:
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'value()该 value 方法从集合的第一个元素中检索给定值:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Speaker', 'price' => 400],
]);
$value = $collection->value('price');
// 200values()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 方法将在传递给该方法的第一个参数评估结果为 true 时执行给定的回调. 集合实例以及传递给 when 方法的第一个参数将被提供给该闭包:
$collection = collect([1, 2, 3]);
$collection->when(true, function (Collection $collection, bool $value) {
return $collection->push(4);
});
$collection->when(false, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 4]第二个回调可以传递给 when 方法。当传递给 when 方法的第一个参数评估结果为 false 时,第二个回调将会执行:
$collection = collect([1, 2, 3]);
$collection->when(false, function (Collection $collection, bool $value) {
return $collection->push(4);
}, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]对于 when 的逆操作,请参阅 unless 方法。
当为空时()该 whenEmpty 方法将在集合为空时执行给定的回调:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom']
$collection = collect();
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Adam']第二个闭包可以传递给 whenEmpty 方法,该闭包会在集合不为空时执行:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
}, function (Collection $collection) {
return $collection->push('Taylor');
});
$collection->all();
// ['Michael', 'Tom', 'Taylor']对于 whenEmpty 的逆操作, 请参阅 whenNotEmpty 方法.
whenNotEmpty()whenNotEmpty 方法将在集合不为空时执行给定的回调:
$collection = collect(['Michael', 'Tom']);
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom', 'Adam']
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// []第二个闭包可以传递给 whenNotEmpty 方法,该闭包在集合为空时执行:
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
}, function (Collection $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 方法使用“严格”比较进行过滤,或者使用 whereNull 和 whereNotNull 方法来过滤 null 值。
可选地,您可以将一个比较运算符作为第二个参数传入。支持的运算符有:===, !==, !=, ==, =, <>, >, <, >=, 和 <=:
$collection = collect([
['name' => 'Jim', 'platform' => 'Mac'],
['name' => 'Sally', 'platform' => 'Mac'],
['name' => 'Sue', 'platform' => 'Linux'],
]);
$filtered = $collection->where('platform', `!=`, 'Linux');
$filtered->all();
/*
[
['name' => 'Jim', 'platform' => 'Mac'],
['name' => 'Sally', 'platform' => 'Mac'],
]
*/whereStrict()此方法具有与 where 方法相同的签名;然而,所有值都使用“严格”比较进行比较。
介于之间()该 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' => 'Desk', 'price' => 200],
['product' => 'Bookcase', 'price' => 150],
]
*/该 whereIn 方法在检查项值时使用“宽松”比较,这意味着具有整数值的字符串将被视为与相同值的整数相等。使用 whereInStrict 方法来使用“严格”比较进行过滤。
whereInStrict()此方法具有与 whereIn 方法相同的签名;但是,所有值都使用“严格”比较进行比较。
whereInstanceOf()该 whereInstanceOf 方法根据给定的类类型过滤集合:
use App\Models\User;
use App\Models\Post;
$collection = collect([
new User,
new User,
new Post,
]);
$filtered = $collection->whereInstanceOf(User::class);
$filtered->all();
// [App\Models\User, App\Models\User]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 方法进行“严格”比较过滤。
严格不包含()此方法具有与 whereNotIn 方法相同的签名;然而,所有值都使用“严格”比较进行比较。
whereNotNull()该 whereNotNull 方法返回集合中给定键不为 null 的项:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]);
$filtered = $collection->whereNotNull('name');
$filtered->all();
/*
[
['name' => 'Desk'],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]
*/whereNull()方法 whereNull 返回集合中给定键为 null 的项:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]);
$filtered = $collection->whereNull('name');
$filtered->all();
/*
[
['name' => null],
]
*/wrap()静态 wrap 方法在适用时将给定值包装到集合中:
use Illuminate\Support\Collection;
$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]]集合也支持“高阶消息”,它们是用于在集合上执行常见操作的快捷方式。提供高阶消息的集合方法有:平均值,平均,包含,每个,所有,筛选,第一个,扁平映射,分组,按键分组,映射,最大值,最小值,分区,拒绝,跳过直到,跳过当,部分,排序,降序排序,求和,获取直到,获取当,和唯一。
每个高阶消息都可以作为集合实例上的动态属性进行访问。例如,让我们使用 each 高阶消息来调用集合中每个对象上的方法:
use App\Models\User;
$users = User::where('votes', `>`, 500)->get();
$users->each->markAsVip();同样,我们可以使用 sum 高阶消息来收集一组用户的“投票”总数:
$users = User::where('group', 'Development')->get();
return $users->sum->votes;[!WARNING]
在深入了解 Laravel 的惰性集合之前,请花些时间熟悉 PHP 生成器。
为了补充已经非常强大的 Collection 类,LazyCollection 类利用 PHP 的 生成器 让你能够处理超大数据集同时保持低内存使用。
例如,想象你的应用程序需要处理一个多 GB 的日志文件,同时利用 Laravel 的集合方法来解析日志。与其一次性将整个文件读入内存,惰性集合可用于在给定时间仅将文件的一小部分保留在内存中:
use App\Models\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
fclose($handle);
})->chunk(4)->map(function (array $lines) {
return LogEntry::fromLines($lines);
})->each(function (LogEntry $logEntry) {
// Process the log entry...
});或者,想象一下,你需要遍历 10,000 个 Eloquent 模型。当使用传统的 Laravel 集合时,所有 10,000 个 Eloquent 模型都必须同时加载到内存中:
use App\Models\User;
$users = User::all()->filter(function (User $user) {
return $user->id > 500;
});然而,查询构建器的cursor方法返回一个LazyCollection实例。这让您仍然只对数据库执行一次查询,但每次只在内存中加载一个 Eloquent 模型。在此示例中,直到我们实际单独遍历每个用户时,filter回调才会被执行,从而大幅降低内存使用量:
use App\Models\User;
$users = User::cursor()->filter(function (User $user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}要创建延迟集合实例,您应该将一个 PHP 生成器函数传递给该集合的 make 方法:
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
fclose($handle);
});几乎所有在Collection类上可用的方法,在LazyCollection类上也可用。这两个类都实现了Illuminate\Support\Enumerable契约,该契约定义了以下方法:
all
average
avg
chunk
chunkWhile
collapse
collect
combine
concat
contains
containsStrict
count
countBy
crossJoin
dd
diff
diffAssoc
diffKeys
dump
duplicates
duplicatesStrict
each
eachSpread
every
except
filter
first
firstOrFail
firstWhere
flatMap
flatten
flip
forPage
get
groupBy
has
implode
intersect
intersectAssoc
intersectByKeys
isEmpty
isNotEmpty
join
keyBy
keys
last
macro
make
map
mapInto
mapSpread
mapToGroups
mapWithKeys
max
median
merge
mergeRecursive
min
mode
nth
only
pad
partition
pipe
pluck
random
reduce
reject
replace
replaceRecursive
reverse
search
shuffle
skip
slice
sole
some
sort
sortBy
sortByDesc
sortKeys
sortKeysDesc
split
sum
take
tap
times
toArray
toJson
union
unique
uniqueStrict
unless
unlessEmpty
unlessNotEmpty
unwrap
values
when
whenEmpty
whenNotEmpty
where
whereStrict
whereBetween
whereIn
whereInStrict
whereInstanceOf
whereNotBetween
whereNotIn
whereNotInStrict
wrap
zip
[!WARNING]
修改集合的方法(例如shift、pop、prepend等)在LazyCollection类上不可用。
除了定义在 Enumerable 契约中的方法, LazyCollection 类还包含以下方法:
获取直到超时()takeUntilTimeout 方法返回一个新的惰性集合,该集合将枚举值,直到指定时间。在此时间之后,该集合将停止枚举:
$lazyCollection = LazyCollection::times(INF)
->takeUntilTimeout(now()->addMinute());
$lazyCollection->each(function (int $number) {
dump($number);
sleep(1);
});
// 1
// 2
// ...
// 58
// 59为了说明此方法的用法,想象一个使用游标从数据库提交发票的应用程序。你可以定义一个计划任务,它每15分钟运行一次,并且最多只处理14分钟的发票:
use App\Models\Invoice;
use Illuminate\Support\Carbon;
Invoice::pending()->cursor()
->takeUntilTimeout(
Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')
)
->each(fn (Invoice $invoice) => $invoice->submit());tapEach()虽然 each 方法会立刻为集合中的每个项调用给定的回调, tapEach 方法只会在项逐一从列表中取出时才调用给定的回调:
// Nothing has been dumped so far...
$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {
dump($value);
});
// Three items are dumped...
$array = $lazyCollection->take(3)->all();
// 1
// 2
// 3节流()throttle 方法将对惰性集合进行节流,使得每个值在指定的秒数后返回。此方法在您可能正在与对传入请求进行速率限制的外部 API 交互的场景中特别有用:
use App\Models\User;
User::where('vip', true)
->cursor()
->throttle(seconds: 1)
->each(function (User $user) {
// Call external API...
});remember()remember 方法返回一个新的惰性集合,该集合会记住任何已经枚举过的值,并且在后续的集合枚举中不会再次检索它们:
// No query has been executed yet...
$users = User::cursor()->remember();
// The query is executed...
// The first 5 users are hydrated from the database...
$users->take(5)->all();
// First 5 users come from the collection's cache...
// The rest are hydrated from the database...
$users->take(20)->all();withHeartbeat()withHeartbeat 方法允许你在枚举惰性集合时,以固定的时间间隔执行一个回调。这对于需要定期维护任务的耗时操作特别有用,例如延长锁或发送进度更新:
use Carbon\CarbonInterval;
use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('generate-reports', seconds: 60 * 5);
if ($lock->get()) {
try {
Report::where('status', 'pending')
->lazy()
->withHeartbeat(
CarbonInterval::minutes(4),
fn () => $lock->extend(CarbonInterval::minutes(5))
)
->each(fn ($report) => $report->process());
} finally {
$lock->release();
}
}