這篇筆記用來整理Collection 在Laravel 的實際應用場景。
求和
需求:遍歷$orders 數組,求price 的和。
<?php // 引入package require __DIR__ . '/vendor/autoload.php'; $orders = [[ 'id' => 1, 'user_id' => 1, 'number' => '13908080808', 'status' => 0, 'fee' => 10, 'discount' => 44, 'order_products'=> [ ['order_id'=>1,'product_id'=>1,'param'=>'6寸','price'=>555.00,'product'=>['id'=>1,'name'=>'蛋糕名称','images'=>[]]], ['order_id'=>1,'product_id'=>1,'param'=>'7寸','price'=>333.00,'product'=>['id'=>1,'name'=>'蛋糕名称','images'=>[]]], ], ]];
登入後複製
$sum = 0; foreach ($orders as $order) { foreach ($order['order_products'] as $item) { $sum += $item['price']; } } echo $sum;
登入後複製
$sum = collect($orders)->map(function($order){ return $order['order_products']; })->flatten(1)->map(function($order){ return $order['price']; })->sum(); echo $sum;
登入後複製
map:遍歷集合,傳回一個新的集合。
flatten:將多維數組轉換為一維。
sum:傳回數組的和。
$sum = collect($orders)->flatMap(function($order){ return $order['order_products']; })->pluck('price')->sum(); echo $sum;
登入後複製
flatMap:和map
類似,不過差別在於flatMap
可以直接使用傳回的新集合。
$sum = collect($orders)->flatMap(function($order){ return $order['order_products']; })->sum('price');
登入後複製
sum:可以接收一個列名作為參數來求和。
格式化資料
需求:將如下結構的數組,格式化成下面的新數組。
// 带格式化数组 $gates = [ 'BaiYun_A_A17', 'BeiJing_J7', 'ShuangLiu_K203', 'HongQiao_A157', 'A2', 'BaiYun_B_B230' ]; // 新数组 $boards = [ 'A17', 'J7', 'K203', 'A157', 'A2', 'B230' ];
登入後複製
$res = []; foreach($gates as $key => $gate) { if(strpos($gate, '_') === false) { $res[$key] = $gate; }else{ $offset = strrpos($gate, '_') + 1; $res[$key] = mb_substr($gate , $offset); } } var_dump($res);
登入後複製
$res = collect($gates)->map(function($gate) { $parts = explode('_', $gate); return end($parts); });
登入後複製
$res = collect($gates)->map(function($gate) { return collect(explode('_', $gate))->last(); })->toArray();
登入後複製
explode:將字串分割成陣列
last:取得最後一個元素
統計GitHub Event
#首先,透過此連結取得到個人事件json。
一個PushEvent計
5 分,一個CreateEvent
計4 分,一個IssueCommentEvent計
3 分,一個IssueCommentEvent
#計2 分,除此之外的其它類型的事件計1 分,計算當前用戶的時間得分總和。
$opts = [ 'http' => [ 'method' => 'GET', 'header' => [ 'User-Agent: PHP' ] ] ]; $context = stream_context_create($opts); $events = json_decode(file_get_contents('http://api.github.com/users/0xAiKang/events', false, $context), true);
登入後複製
$eventTypes = []; // 事件类型 $score = 0; // 总得分 foreach ($events as $event) { $eventTypes[] = $event['type']; } foreach($eventTypes as $eventType) { switch ($eventType) { case 'PushEvent': $score += 5; break; case 'CreateEvent': $score += 4; break; case 'IssueEvent': $score += 3; break; case 'IssueCommentEvent': $score += 2; break; default: $score += 1; break; } }
登入後複製
$score = $events->pluck('type')->map(function($eventType) { switch ($eventType) { case 'PushEvent': return 5; case 'CreateEvent': return 4; case 'IssueEvent': return 3; case 'IssueCommentEvent': return 2; default: return 1; } })->sum();
登入後複製
使用集合的鍊式編程,可以很好地解決上面那種多次遍歷的問題。
3.使用集合中的map、pluck、get 方法:$score = $events->pluck('type')->map(function($eventType) { return collect([ 'PushEvent'=> 5, 'CreateEvent'=> 4, 'IssueEvent'=> 3, 'IssueCommentEvent'=> 2 ])->get($eventType, 1); // 如果不存在则默认等于1 })->sum();
登入後複製
class GithubScore { private $events; private function __construct($events){ $this->events = $events; } public static function score($events) { return (new static($events))->scoreEvents(); } private function scoreEvents() { return $this->events->pluck('type')->map(function($eventType){ return $this->lookupEventScore($eventType, 1); })->sum(); } public function lookupEventScore($eventType, $default_value) { return collect([ 'PushEvent'=> 5, 'CreateEvent'=> 4, 'IssueEvent'=> 3, 'IssueCommentEvent'=> 2 ])->get($eventType, $default_value); // 如果不存在则默认等于1 } } var_dump(GithubScore::score($events));
登入後複製
格式化資料
需求:將以下資料格式化成新的結構。
$messages = [ 'Should be working now for all Providers.', 'If you see one where spaces are in the title let me know.', 'But there should not have blank in the key of config or .env file.' ]; // 格式化之后的结果 - Should be working now for all Providers. \n - If you see one where spaces are in the title let me know. \n - But there should not have blank in the key of config or .env file.
登入後複製
$comment = '- ' . array_shift($messages); foreach ($messages as $message) { $comment .= "\n - ${message}"; } var_dump($comment);
登入後複製
$comment = collect($messages)->map(function($message){ return '- ' . $message; })->implode("\n"); var_dump($comment);
登入後複製
多個陣列求差
需求:兩組資料分別代表去年的營收和今年的營收,求每個月的盈虧狀況。
$lastYear = [ 6345.75, 9839.45, 7134.60, 9479.50, 9928.0, 8652.00, 7658.40, 10245.40, 7889.40, 3892.40, 3638.40, 2339.40 ]; $thisYear = [ 6145.75, 6895.00, 3434.00, 9349350, 9478.60, 7652.80, 4758.40, 10945.40, 3689.40, 8992.40, 7588.40, 2239.40 ];
登入後複製
$profit = []; foreach($thisYear as $key => $monthly){ $profit[$key] = $monthly - $lastYear[$key]; } var_dump($profit);
登入後複製
$profit = collect($thisYear)->zip($lastYear)->map(function($monthly){ return $monthly->first() - $monthly->last(); });
登入後複製
zip:將給定數組的值與相應索引處的原始集合的值合併在一起。
建立lookup 陣列
需求:將以下陣列格式化成下面的結果:
$employees = [ [ 'name' => 'example', 'email' => 'example@exmaple.com', 'company' => 'example Inc.' ], [ 'name' => 'Lucy', 'email' => 'lucy@example.com', 'company' => 'ibm Inc.' ], [ 'name' => 'Taylor', 'email' => 'toylor@laravel.com', 'company'=>'Laravel Inc.' ] ]; // 格式化之后的结果 $lookup = [ 'example' => 'example@example.com', 'Lucy' => ‘lucy@example.com’, 'Taylor'=> 'toylor@laravel.com' ];
登入後複製
$emails = []; foreach ($employees as $key => $value) { $emails[$value['name']] = $value['email']; }
登入後複製
$emails = collect($employees)->reduce(function($emailLookup, $employee){ $emailLookup[$employee['name']] = $employee['email']; return $emailLookup; },[]);
登入後複製
reduce:將每次迭代的結果傳遞給下一次迭代直到集合減少為單一值。
3.使用集合的pluck 方法:$emails = collect($employees)->pluck('name', 'email');
登入後複製