Laravel Collection

iffor發表於2021-05-26

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 協議》,轉載必須註明作者和本文連結

相關文章