Laravel Collection

Laravel Collection

Collection 是laravel提供的对 array 进行包装的类。它有如下的特点:

  • 函数式
  • 流式API(Fluent API)
  • 操作代理
  • 可扩展

有一个数组 range(1,100),需要找出大于30的偶数。

过程式常规的实现方式:

$arr = range(1,100);
$result = [];
foreach (range(1,100) as $v){
 if ($v > 30 && $v%2 == 0){ $result[] = $v; }}

Collection 流式和函数式的风格方式

$list = Collection::range(1,100);
$result = $list->filter(function ($v){
 return $v > 30;})->filter(function ($v){
 return $v % 2 ==0;});

通过将不同的过滤逻辑封装到不同的函数中,连续的对同一个列表调用 filter 方法,使得代码看起来情绪,写起来流畅。

操作代理的意思:需要对 Collection 执行某个操作,但具体操作细节在 Collection 元素对象上实现。

有一个名为 StudentScore 对象,该对象包含 chinesemath 两个分数的属性。现在需要分别计算列表中 chinses
math 的最高多。

非代理方式

class StudentScore
{
public $math;
public $chinese;

 /** * StudentScore constructor. * @param $math * @param $chinese */ public function __construct($math, $chinese) { $this->math = $math; $this->chinese = $chinese; }}

$scores = collect([new StudentScore(mt_rand(60, 120), mt_rand(60, 120)),
new StudentScore(mt_rand(60, 120), mt_rand(60, 120)),
new StudentScore(mt_rand(60, 120), mt_rand(60, 120)),
]);

// 语文最高分
$chineseMaxScore = $scores->max(function (StudentScore  $score){
return $score->chinese;
});

// 数学最高分
$mathMaxScore = $scores->max(function (StudentScore  $score){
return $score->math;
});

// 全部学科最高分
$maxScore = $scores->max(function (StudentScore $score){
return max($score->chinese,$score->math);
});

如果最高分的逻辑计算需要在不同的地方多次使用,那么我们可以通过 Collection 的代理的方式,把具体的逻辑封装到类内部。

class StudentScore
{
 public $math; public $chinese;
 /** * StudentScore constructor. * @param $math * @param $chinese */ public function __construct($math, $chinese) { $this->math = $math; $this->chinese = $chinese; }
 function chineseMaxScore(){ return $this->chinese; }
 function mathMaxScore(){ return $this->math; }
 function maxScore(){ return max($this->math,$this->chinese); }}

$scores = collect([new StudentScore(mt_rand(60, 120), mt_rand(60, 120)),
 new StudentScore(mt_rand(60, 120), mt_rand(60, 120)), new StudentScore(mt_rand(60, 120), mt_rand(60, 120)), ]);
$maxProxy = $scores->max;
$chineseMaxScore = $maxProxy->chineseMaxScore();
$mathMaxScore = $maxProxy->mathMaxScore();
$maxScore = $maxProxy->maxScore();
dd($chineseMaxScore,$mathMaxScore,$maxScore);

使用proxy模式的优点是,可以把逻辑封装到类内部,多次使用。

某些场景下我们需要功能 Collection 并未提供,由于 Collection 使用了 Macroable,可以使用 macr 接口扩展功能。


// 为 Collection 扩展 `pass` 方法
Collection::macro("pass",function ($cb){
 return $this->filter($cb);});

$scores = Collection::range(1,10);
$passScores = $scores->pass(function ($v){
 return $v > 5;});
dd($passScores);// output: [6,7,8,9,10]
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!