跳转至

Collection 集合#

概述#

Illuminate\Support\Collection 提供一个处理数组的数据封装类。

本文核心文件(含相关注释):Collection.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]);
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) 与多个集合互相组合,返回组合后的笛卡尔积集合

collect(['X', 'XL'])->crossJoin(['红色', '白色', '紫色'], ['长款', '短款']);
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($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 方法:

Collection::macro('prefix', function ($prefix = '') {  // 参数传入位置
    return $this->map(function ($value) use ($prefix) {  // 注意此处是 $this
        return $prefix.$value;
    });
});

collect([1, 2, 3])->prefix('tests');
Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => tests1
            [1] => tests2
            [2] => tests3
        )

)

通常在服务提供者中定义扩展集合方法。

相关文件#


最后更新: 2020年6月16日 00:12:37