Collection 集合#
概述#
Illuminate\Support\Collection 提供一个处理数组的数据封装类。
本文核心文件(含相关注释):Collection.php
创建集合#
```php tab="PHP" use Illuminate\Support\Collection;
// 类直接创建 $collect = new Collection([1, 3, 5]);
// 静态方法创建 $collect = Collection::make([1, 2, 4]);
// 创建指定数量的集合 $collect = Collection::times(3);
// 创建指定数量,并经过回调函数处理的集合 \(collect = Collection::times(3, function (\)value) { return [ 'value' => \(value, 'name' => 'tests:'.\)value, ]; });
// 通过函数快速创建 $collect = collect([1, 2, 3]);
``` tab="Result"
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => 1
[1] => 3
[2] => 5
)
)
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => 1
[1] => 2
[2] => 4
)
)
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
)
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => Array
(
[value] => 1
[name] => tests:1
)
[1] => Array
(
[value] => 2
[name] => tests:2
)
[2] => Array
(
[value] => 3
[name] => tests:3
)
)
)
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => 1
[1] => 3
[2] => 5
)
)
集合方法#
all()#
all() 返回集合所有数据
collect([1, 2, 3])->all(); // [1, 2, 3];
lazy()#
lazy() 创建一个惰性集合(支持迭代器,性能更优)
avg()#
avg($callback = null) 获取平均值,支持回调函数
collect([1, 2, 3])->avg(); // 2
$collect = collect([
['name' => 1, 'value' => '123'],
['name' => 2, 'value' => '222'],
['name' => 3, 'value' => '444'],
]);
// 指定字段
$collect->avg('value'); // 263
// 回调函数
$collect->avg(function ($value) {
return $value['value'];
}); // 263
median()#
median($key = null) 获取中位数
collect([1, 2, 3])->median(); // 2
collect([
['name' => 1, 'value' => '123'],
['name' => 2, 'value' => '222'],
['name' => 3, 'value' => '444'],
])->median('value'); // 222
源码用了一些技巧,可读源码学习。
mode()#
collapse()#
contains()#
crossJoin()#
crossJoin(...$lists) 与多个集合互相组合,返回组合后的笛卡尔积集合
```php tab="PHP" collect(['X', 'XL'])->crossJoin(['红色', '白色', '紫色'], ['长款', '短款']);
``` tab="Result"
Illuminate\Support\Collection {#3029
all: [
[
"X",
"红色",
"长款",
],
[
"X",
"红色",
"短款",
],
[
"X",
"白色",
"长款",
],
[
"X",
"白色",
"短款",
],
[
"X",
"紫色",
"长款",
],
[
"X",
"紫色",
"短款",
],
[
"XL",
"红色",
"长款",
],
[
"XL",
"红色",
"短款",
],
[
"XL",
"白色",
"长款",
],
[
"XL",
"白色",
"短款",
],
[
"XL",
"紫色",
"长款",
],
[
"XL",
"紫色",
"短款",
],
],
}
该方法常用于电商。方法存在一些技巧。
diff()#
diff($items) 返回两个数组的差集数组。该数组包括了所有在被比较的数组中,但是不在任何其他参数数组中的键值。在返回的数组中,键名保持不变。
collect([1, 2, 3, 4, 5])->diff([2, 4]); // collect([0 => 1, 2 => 3, 4 => 5])
collect([1, 2, 3, 4, 5])->diff(collect([6])); // collect([1, 2, 3, 4, 5])
diffUsing()#
diffUsing($items, callable $callback) 比较两个数组的键值(使用用户自定义函数比较键值),并返回差集。该数组包括了所有在被比较的数组中,但是不在任何其他参数数组中的键值。在返回的数组中,键名保持不变。
$callback 回调对照函数。在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数
collect([1, 2, 3, 4, 5])->diffUsing([2, 4], function ($a, $b) {
if ($a === $b) {
return 0;
}
return $a > $b ? 1 : -1;
}); // collect([0 => 1, 2 => 3, 4 => 5])
collect([1, 2, 3, 4, 5])->diffUsing([2, 4], function ($a, $b) {
if ($a === $b) {
return 0;
}
return $a > $b ? -1 : 1;
}); // collect([0 => 1, 2 => 3, 4 => 5])
需要在深刻理解下...
diffAssoc()#
diffAssocUsing()#
diffKeys()#
diffKeysUsing()#
duplicates()#
duplicatesStrict()#
except()#
except($keys) 返回排除指定 key 的新集合
collect(['a' => 1, 'b' => 2, 'c' => 3])->except(['a', 'b']);
// collect(['c' => 3])
filter()#
filter(callable $callback = null) 通过给定的回调函数过滤集合,保留通过了解的集合数据;如果不设置回调函数,则集合中所有值符合 false 的将会被移除。
collect(['a' => 1, 'b' => 2, 'c' => '', 'd' => 0])->filter();
// collect(['a' => 1, 'b' => 2])
collect(['a' => 1, 'b' => 2, 'c' => '', 'd' => 0])->filter(function ($value) {
return $value !== 0;
});
// collect(['a' => 1, 'b' => 2, 'c' => ''])
first()#
first(callable $callback = null, $default = null) 从集合中返回符合条件的第一个值,支持回调函数;$default 为默认值。
collect()->first(); // null
collect()->first(null, 1); // 1
collect([1, 2])->first(function ($value) {
return $value == 2;
}); // 2
collect([1, 2])->first(function ($value) {
return $value == 3;
}); // null
collect([1, 2])->first(function ($value) {
return $value == 3;
}, function () {
return 333;
}); // 333
flatten()#
flatten($depth = INF) 将多维集合转换为一维集合,其中 $depth 为转换深度,默认无穷大。
INF为 PHP 常量,含义:无穷
collect(['a' => 1, 'b' => [2, 3]])->flatten(); // collect([1, 2, 3])
collect(['a' => 1, 'b' => [2, 'c' => 3, 'd' => [4, 5]]])->flatten(1); // collect([1, 2, 3, [4, 5]])
flip()#
flip() 将集合的键和对应的值进行互换;转换后,遇到相同的键,后面的值会替换前面的
collect(['a' => 1, 'b' => 2])->flip(); // collect(['1' => 'a', '2' => 'b'])
collect(['a' => 1, 'b' => 2 , 'c' => 2])->flip(); // collect(['1' => 'a', '2' => 'c'])
forget()#
forget($keys) 删除指定 keys 的值,keys 可以是数组;并返回当前数组
collect(['a' => 1, 'b' => 2])->forget(['a', 'b']);
// Illuminate\Support\Collection {
// all: [],
// }
get()#
get($key, $default = null) 返回集合中某个元素的值,如果不存在,可获取 $default 的值,$default 可以为回调函数
collect(['a' => 1])->get('a'); // 1
collect(['a' => 1])->get('b'); // null
collect(['a' => 1])->get('b', 222); // 222
collect(['a' => 1])->get('b', fn() => 111); // 111
groupBy()#
keyBy()#
keyBy($keyBy) 以指定的键作为集合的键。如果多个集合项具有相同的键,则只有最后一个集合项会显示在新集合中
collect([
['a' => 11, 'b' => 22],
['a' => 33, 'b' => 44],
])->keyBy('a');
// collect([
// 11 => ['a' => 11, 'b' => 22],
// 33 => ['a' => 33, 'b' => 44],
// ])
collect([
['a' => 11, 'b' => 22],
['a' => 33, 'b' => 44],
])->keyBy(function ($value) {
return 'prefix'.$value['a'];
});
// collect([
// 'prefix11' => ['a' => 11, 'b' => 22],
// 'prefix33' => ['a' => 33, 'b' => 44],
// ])
has()#
has($key) 判定键是否存在,支持多个传入,必须所有满足,才能返回 true
collect(['a' => 1, 'b' => 2, 'c' => 2])->has('a'); // true
collect(['a' => 1, 'b' => 2, 'c' => 2])->has('a', 'b'); // true
collect(['a' => 1, 'b' => 2, 'c' => 2])->has(['a', 'b']); // true
collect(['a' => 1, 'b' => 2, 'c' => 2])->has('a', 'd']); // false
implode()#
implode($value, $glue = null) 将集合合并为字符串
collect([1, 2])->implode('##'); // 1##2
collect([['a' => 11, 'b' => 22], ['a' => 33, 'b' => 44]])->implode('a', '@@'); // 11@@33
intersect()#
intersect($items) 比较数组,返回两个数组的交集(只比较键值)
collect(['a' => 1, 'b' => 2, 'c' => 3])->intersect(['b' => 2, 'c' => 4, 'd' => 3); // collect(['b' => 2, 'c' => 3])
collect(["red", "green", "blue", "yellow"])->intersect(["red", "green", "yellow"]); // collect(["red", "green", "yellow"])
intersectByKeys()#
intersectByKeys($items) 比较数组,返回两个数组的交集(只比较键名)
collect(['a' => 1, 'b' => 2, 'c' => 3])->intersectByKeys(['b' => 2, 'c' => 4]); // collect(['b' => 2, 'c' => 3])
collect(["red", "green", "blue", "yellow"])->intersectByKeys(["red", "green", "yellow"]); // collect(["red", "green", "blue"])
isEmpty()#
isEmpty() 判定数据集合是否为空,如果集合为空,返回 true ,否则返回 false
collect([])->isEmpty(); // true
join()#
join($glue, $finalGlue = '') 将集合中的值用字符串连接
collect([1, 2, 3])->join('##'); // 1##2##3
collect([1, 2, 3])->join('##', '@@'); // 1##2@@3
collect([1, 2, 3])->join('、', '和'); // 1、2和3
keys()#
keys() 返回集合中所有键的集合
collect(['a' => 1, 'b' => 2])->keys(); // collect(['a', 'b'])
last()#
last(callable $callback = null, $default = null) 获取集合中的最后一个或者符合回调函数的最后一个,如果不存在,可设置默认值
collect([1, 2, 3, 4, 5])->last(); // 5
collect([])->last(null ,1); // 1
collect([1, 2, 3, 4, 5])->last(function ($value) {
return $value <= 4;
}); // 4
collect([1, 2, 3, 4, 5])->last(function ($value) {
return $value >= 6;
}, 6); // 6
pluck()#
pluck($value, $key = null) 返回集合中指定元素的值,$key 的值设置为以下标
collect([['a' => 1, 'b' => 11], ['a' => 2, 'b' => 22]])->pluck('a');
// collect([1, 2]);
collect([['a' => 1, 'b' => 11], ['a' => 2, 'b' => 22]])->pluck('a', 'b');
// collect(['11' => 1, '22' => 2])
如果存在重复的键,则最后一个匹配元素将被插入到弹出的集合中
collect([['a' => 1, 'b' => 11], ['a' => 2, 'b' => 11]])->pluck('a', 'b');
// // collect(['11' => 2])
map()#
map(callable $callback) 遍历集合并将值和下标,使用回调函数处理集合数据,并返回新的集合
collect([['a' => 1, 'b' => 11], ['a' => 2, 'b' => 11]])->map(function ($value) {
$value['c'] = 1;
return $value;
});
// collect([['a' => 1, 'b' => 11, 'c' => 1], ['a' => 2, 'b' => 11, 'c' => 1]]);
mapToDictionary()#
mapWithKeys()#
merge()#
merge($items) 把一个或多个数组/集合合并为一个集。
collect(['a' => 1, 'b' => 2])->merge(['a' => 111]); // collect(['a' => 1111, 'b' => 2]);
collect(['a' => 1, 'b' => 2])->merge(collect(['a' => 111])); // collect(['a' => 1111, 'b' => 2]);
collect(['a' => ['c' => 1], 'b' => 2])->merge(collect(['a' => 111])); // collect(['a' => 1111, 'b' => 2]);
mergeRecursive()#
mergeRecursive($items) 递归地一个或多个数组/集合合并为一个集。
collect(['a' => 1, 'b' => 2])->mergeRecursive(['a' => 111]); // collect(['a' => [1, 111], 'b' => 2]);
collect(['a' => 1, 'b' => 2])->mergeRecursive(collect(['a' => 111])); // collect(['a' => [1, 111], 'b' => 2]);
collect(['a' => ['c' => 1], 'b' => 2])->mergeRecursive(collect(['a' => 111])); // collect(['a' => ['c' => 1, 0 => 111], 'b' => 2]);
combine()#
combine($values) 通过合并两个数组/集合(一个为键名数组/集合,一个为键值数组/集合)来创建一个新集合
collect(['a', 'b'])->combine([1, 2]); // collect(['a' => 1, 'b' => 2])
collect(['a', 'b'])->combine([1, 2, 3]); // collect([false])
union()#
union($items) 将两个数组或集合进行相加
collect(['a' => 1, 'b' => 2])->union(['a' => 111, 'c' => 3]); // collect(['a' => 1, 'b' => 2, 'c '=> 3])
collect(['a' => 1, 'b' => 2])->merge(['a' => 111, 'c' => 3]); // collect(['a' => 111, 'b' => 2, 'c '=> 3])
nth()#
nth($step, $offset = 0) 创建由每隔 $step 个,并便宜 $offset 元素组成的一个新集合
collect([1, 2, 3, 4, 5, 6, 7, 8])->nth(3); // collect(1, 4, 7)
collect([1, 2, 3, 4, 5, 6, 7, 8])->nth(3, 2); // collect(3, 6)
only()#
only($keys) 返回指定键的集合
collect(['a' => 1, 'b' => 2, 'c' => 3])->only(['a', 'b']);
collect(['a' => 1, 'b' => 2, 'c' => 3])->only('a', 'b');
collect(['a' => 1, 'b' => 2, 'c'])->only(collect(['a', 'b']));
// 三个返回结果一致
// collect(['a' => 1, 'b' => 2])
pop()#
pop() 移除并返回集合中的最后一个值
$collect = collect([1, 2, 3]);
$collect->pop(); // 3
$collect->all(); // [1, 2]
prepend()#
prepend($value, $key = null) 在集合开头插入一个值,并返回集合
collect([1, 2, 3])->prepend(4); // collect([4, 1, 2, 3])
collect([1, 2, 3])->prepend(4, 'a'); // collect(['a' => 4, 1, 2, 3])
push()#
push(...$values) 在集合结尾插入一个或多个值
collect([1, 2, 3])->push(4, 5); // collect([1, 2, 3, 4, 5])
collect([1, 2, 3])->push(4); // collect([1, 2, 3, 4])
concat()#
concat($source) 将新的集合或数组附加到当前集合结尾
collect([1, 2, 3])->concat([4, 5]); // collect([1, 2, 3, 4, 5])
collect([1, 2, 3])->concat(collect([4, 5])); // collect([1, 2, 3, 4, 5])
pull()#
pull($key, $default = null) 从集合中获取并移除指定键的值,如果不存在,可获取默认值($default)
$collect = collect(['a' => 1, 'b' => 2]);
$collect->pull('a'); // 1
$collect->all(); // ['b' => 2]
$collect->pull('c', '3'); // 3
$collect->all(); // ['b' => 2]
put()#
put($key, $value) 将指定的键和值写入到集合,并返回集合;方法逻辑同 offsetSet,区别在于 put() 返回当前集合
collect(['a' => 1])->put('b', 2); // collect(['a' => 1, 'b' => 2])
random()#
random($number = null) 随机返回一个值或指定数量值的集合(不返回键)
collect([1, 2, 3, 4])->random(); // 4(每次随机)
collect([1, 2, 3, 4])->random(2); // collect([2, 3])(每次随机)
collect(['a' => 1, 'b' => 2, 'c' => 3])->random(); // 3(每次随机)
collect(['a' => 1, 'b' => 2, 'c' => 3])->random(2); // collect([1, 2])(每次随机)
reduce()#
reduce(callable $callback, $initial = null) 通过回调函数,迭代每次的值,$initial 为初始值
collect([
['a' => 1, 'b' => 11],
['a' => 2, 'b' => 22],
['a' => 3, 'b' => 33],
['a' => 4, 'b' => 44],
])->reduce(function ($item, $value) {
$item[] = $value['a'] * 2;
return $item;
}, [5]);
// [5, 2, 4, 6, 8]
replace()#
replace() 方法类似于 merge() ;但是,不仅可以覆盖匹配到的相同字符串键的集合项,而且也可以覆盖数字键的集合项
collect(['a' => 1, 'b' => 2])->replace(['a' => 2]); // collect(['a' => 2, 'b' => 2])
collect([1, 2])->replace([0 => 2]); // collect([2, 2])
replaceRecursive()#
replaceRecursive($items) 递归地使用参数的集合/数组的值替换当前集合的值
collect(['a' => 1, 'b' => [2, 3]])->replaceRecursive(['a' => 5, 'b' => [4]]);
// collect(['a' => 5, 'b' => [4, 3]])
适合配置文件深层继承
reverse()#
reverse() 返回逆向排序集合
collect(['a' => 1, 'b' => 2])->reverse(); // collect(['b' => 2, 'a' => 1])
search()#
search($value, $strict = false) 搜索集合中给定的值并返回下标;其中值支持回调函数;$strict 为是否精准匹配
collect(['a' => 1, 'b' => 2])->search(1); // a
collect(['a' => 1, 'b' => 2])->search(1, true); // a
collect(['a' => 1, 'b' => 2])->search('1', true); // false
collect(['a' => 1, 'b' => 2])->search(fn($value) => $value == 1); // a
shift()#
shift() 从集合移除并返回第一个值
collect([1, 2, 3])->shift(); // 1
shuffle()#
shuffle($seed = null) 将集合随机打乱,并返回新的集合;$seed 给随机数发生器播种。
collect([1, 2, 3])->shuffle(); // collect([2, 1, 3]) 每次随机
collect([1, 2, 3])->shuffle(1); // collect([2, 1, 3]) 每次随机
skip()#
skip($count) 跳过指定数量的集合,支持负数
collect([1, 2, 3])->skip(1); // collect([2, 3])
collect([1, 2, 3])->skip(-1); // collect([3])
skipUntil()#
skipWhile()#
slice()#
split()#
chunk()#
chunk($size) 针对集合数据进行分组
$chunks = collect([1, 2, 3, 4, 5, 6, 7])->chunk(3); // 按三个一组进行拆分
$chunks->toArray(); // [[1, 2, 3], [4, 5, 6], [7]]t
当使用如 Bootstrap 那样的栅格系统时,该方法在视图中相当有用。想象一下你有个想在栅格显示的 Eloquent 模型:
@foreach ($products->chunk(3) as $chunk)
<div class="row">
@foreach ($chunk as $product)
<div class="col-xs-4">{{ $product->name }}</div>
@endforeach
</div>
@endforeach
sort()#
sortDesc()#
sortBy()#
sortByDesc()#
sortKeys()#
sortKeysDesc()#
splice()#
take()#
take($limit) 从集合中获取指定数量的值,支持负数
collect([1, 2, 3])->take(2); // collect([1, 2])
collect([1, 2, 3])->take(-2); // collect([2, 3])
takeUntil()#
takeWhile()#
transform()#
values()#
values() 重置集合数据的下标
collect(['a' => 1, 'b' => 2])->values();
// Illuminate\Support\Collection {
// all: [
// 1,
// 2,
// ],
// }
zip()#
pad()#
pad($size, $value) 补足指定数量的指定值到集合数据中
collect([1, 2, 3])->pad(6, 123); // collect([1, 2, 3, 123, 123, 123])
getIterator()#
getIterator() 返回当前集合的数组迭代器
count()#
count() 返回集合的总数
collect([1, 2, 3])->count(); // 3
add()#
add($item) 追加一个数据到集合中,并返回当前集合
collect([1, 2, 3])->add(4); // collect([1, 2, 3, 4])
toBase()#
toBase() 基于当前集合,返回一个新的集合
offsetExists()#
offsetExists($key) 判定集合的指定下标是否存在
$collect = collect([
'name' => 1,
'username' => 222,
]);
$collect->offsetExists('name'); // 1
offsetGet()#
offsetGet($key) 获取集合中指定下标的数据
$collect = collect([
'name' => 111,
'username' => 222,
]);
$collect->offsetGet('name'); // 111
offsetSet()#
offsetSet($key, $value) 向集合设置指定下标的数据;若下标未定义(null),则追加数据
$collect = collect([
'name' => 111,
'username' => 222,
]);
$collect->offsetSet('name', '123123'); // 赋值
$collect->offsetGet('name'); // 123123
$collect->offsetSet(null, '3234234'); // 追加
offsetUnset()#
offsetUnset($key) 删除集合中指定下标的数据
$collect = collect([
'name' => 111,
'username' => 222,
]);
$collect->offsetUnset('name');
扩展集合#
集合都是「可宏扩展」(macroable) 的,它允许你在执行时将其它方法添加到 Collection 类。
例如,通过下面的代码在 Collection 类中添加一个 prefix 方法:
```php tab="PHP" Collection::macro('prefix', function ($prefix = '') { // 参数传入位置 return \(this->map(function (\)value) use ($prefix) { // 注意此处是 $this return \(prefix.\)value; }); });
collect([1, 2, 3])->prefix('tests');
``` tab="Result"
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => tests1
[1] => tests2
[2] => tests3
)
)
通常在服务提供者中定义扩展集合方法。
相关文件#
- LearnKu:https://learnku.com/docs/laravel/7.x/collections/7483
- 集合类:
/vendor/laravel/framework/src/Illuminate/Support/Collection.php - 创建集合:
/app/Console/Commands/Collection/Create.php /app/Console/Commands/Collection/Functions.php