This note is used to organize the actual application scenarios of Collection in Laravel.
Summing
Requirement: Traverse the $orders array and find the sum of prices.
<?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: Traverse the collection and return a new collection.
flatten: Convert a multidimensional array to one dimension.
sum: Returns the sum of the array.
$sum = collect($orders)->flatMap(function($order){ return $order['order_products']; })->pluck('price')->sum(); echo $sum;
flatMap: Similar to map
, but the difference is that flatMap
can directly use the returned new collection.
$sum = collect($orders)->flatMap(function($order){ return $order['order_products']; })->sum('price');
sum: You can receive a column name as a parameter for summation.
Formatting data
Requirements: Format the array with the following structure into the new array below.
// 带格式化数组 $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: Split the string into an array
last: Get the last element
Statistics GitHub Event
First, get the personal event json through this link.
One PushEvent is worth
5 points, one CreateEvent
is worth 4 points, one IssueCommentEvent is worth
3 points, one IssueCommentEvent
It is worth 2 points, other types of events are worth 1 point, and the total time score of the current user is calculated.
$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();
Using chain programming of the set can well solve the above multiple traversal problems.
3. Use the map, pluck, and get methods in the collection:$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));
Format data
Requirement: The following data is formatted into a new structure.
$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);
Multiple arrays to find differences
Requirements: Two sets of data represent last year's data respectively Revenue and this year's revenue, find the profit and loss for each month.
$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: Merge the values of the given array with the values of the original collection at the corresponding index.
Create a lookup array
Requirements: Format the following array into the following result:
$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: Pass the result of each iteration to the next iteration until the set is reduced to a single value.
3. Use the pluck method of collection:$emails = collect($employees)->pluck('name', 'email');