Home > Article > Backend Development > How to write code using Laravel Collections class
This article mainly introduces how to write code using the Laravel Collections class. It has certain reference value. Now I share it with you. Friends in need can refer to it
Laravel provides some awesome components , in my opinion, it is the one that provides the best component support among all current web frameworks. It not only provides out-of-the-box views, authentication, sessions, caching, Eloquent, queues, data validation and other components. There are even development tools provided (Valet and Homestead).
However, the most powerful feature of this framework is often ignored by newcomers - the Collection (collection) class. In this article, we'll explore how to use collections to improve coding efficiency, readable lines of code, and write leaner code.
The initial exposure to using collections came from developers using Eloquent to execute database queries and using the foreach statement to traverse the model collection from the returned data.
However, beginners may not notice that collections provide more than 90 methods to operate on the underlying data. What's even better is that almost all methods support chaining operations, making your code read like prose. This makes your code easier to read, both for you and other users.
Haven’t gotten to the point yet? Okay, let’s review a simple code snippet and see how we can use collections to write thick, fast, and powerful code.
Let's build a real world. Suppose we query some API interfaces and obtain the following result set saved in an array:
<?php // API 请求返回的结果 $data = [ ['first_name' => 'John', 'last_name' => 'Doe', 'age' => 'twenties'], ['first_name' => 'Fred', 'last_name' => 'Ali', 'age' => 'thirties'], ['first_name' => 'Alex', 'last_name' => 'Cho', 'age' => 'thirties'], ];
We see that the array contains first name, last name and age range. Now, we assume that we get a age(age) user with 30 years old(thirties) from the record, and then proceed# based on the last name(last name) ##Sort(sort). Finally, we also hope that the returned result is a single string, so that each user has an exclusive new line. Finally, we also hope that the returned result is
This requirement seems not difficult to achieve, now let us see how to implement this function using PHP:// 依据姓氏排序 usort($data, function ($item1, $item2) { return $item1['last_name'] <=> $item2['last_name']; }); // 依据年龄范围分组 $new_data = []; foreach ($data as $key => $item) { $new_data[$item['age']][$key] = $item; } ksort($new_data, SORT_NUMERIC); // 从年龄为 30 岁组里获取用户全名 $result = array_map(function($item) { return $item['first_name'].' '.$item['last_name']; }, $new_data['thirties']); // 将数组转换为字符串并以行分隔符分隔 $final = implode("\n", $result); // 译注:原文是 $final = implode($results, "\n"); implode函数接收两种顺序的参数,为了保持与文档一致所以我这边做了调整。Our implementation code exceeds 20 lines , and very inelegant. Remove comments and newline-related code, and this code will become difficult to read. Furthermore, we also need to use temporary variables and the unfriendly sort method built into PHP. Now, let’s see how simple it is with the Collection class:
collection($data)->where('age', 'thirties') ->sortBy('last_name') ->map(function($item){ return $item['first_name'].' '.$item['last_name']; }) ->implode("\n");Wow! Our code went from 20 lines to 6 lines. Not only does the code now run much smoother, but methods are implemented without the need for comments to tell us what problem they are dealing with. However, there is still one problem that prevents our code from being as good as the perfect stage... It is the
map method used to compare first name and last name. Frankly, this isn't really a big deal, but it provides motivation for exploring macro concepts.
Extending CollectionsThe Collection class, like other Laravel components, supports macros, which means you can add methods to it and use them later.Tip: If you want new methods to be available everywhere, you should add them to the service provider. I like to create a MacroServiceProvider to implement this function, whichever you like.Let's add a method that will concatenate any number of fields provided by the array and return a string result:
Collection::macro('toConcatenatedString', function ($fields = [], $separator = ' ') { return $this->map(function($item) use ($fields, $separator) { return implode($separator, array_map(function ($el) use ($item) { return $item[$el]; }, $fields) ); })->implode("\n"); });After adding this method, our code is basically perfect:
collect($data)->where('age', 'thirties') ->sortBy('last_name') ->toConcatenatedString(['first_name', 'last_name']);Our code has been streamlined from more than 20 chaotic lines to 3 lines. The code is clean and tidy and has clear functions that anyone can understand immediately. Another exampleNow let’s look at the second example, assuming we have a list of users, we need to filter them out based on role, and then further if their registration time is 5 Years or older and
last name starts with the letters A-M only gets the first user.
The data is similar to the following:<?php // API 请求返回的结果 $users = [ ['name' => 'John Doe', 'role' => 'vip', 'years' => 7], ['name' => 'Fred Ali', 'role' => 'vip', 'years' => 3], ['name' => 'Alex Cho', 'role' => 'user', 'years' => 9], ];If we are using PHP implementation, our code looks as follows:
$subset = []; foreach ($users as $user) { if ($user['role'] === 'vip' && $user['years'] >= 5) { if (preg_match('/\s[A-Z]/', $user['name'])) { $subset[] = $user; } } } return reset($subset)
Note: You can The second if statement is moved inside the first one, but I personally like to use no more than two conditionals in a single if statement because I think more than 2 conditionals make the code difficult to read.This code is not too bad, but we still need to use temporary variables, and we also need to use the
reset function to reset the pointer to the first user. Our code also has four levels of indentation, which makes parsing the code more challenging.
Instead, let’s see how collections handle this problem:collect($users)->where('role', 'vip') ->map(function($user) { return preg_match('/\s[A-Z]/', $user['name']); }) ->firstWhere('years', '>=', '5');
我们将代码简化到了之前的一般左右,每一步过滤处理清晰明了,并且我们不需要引入临时变量。
遗憾的是目前集合还不支持正则匹配,所以我们使用 map 方法,不过我们可以为这个功能创建一个宏:
Collection::macro('whereRegex', function($expression, $field) { return $this->map(function ($item) use ($expression, $field) { return preg_match($expression, $item[$field]); }) });
得益于宏方法,我们的代码现在看起来如下:
collect($users) -> where('role', 'vip') -> whereRegex('/\s[A-Z]/', 'name') -> firstWhere('years', '>=', 5);
注意: 为了简单起见,我们的红仅仅适用于数组集合。如果你计划让它们可以在 Eloquent 集合上使用,你需要在此场景下做相应的代码处理才行。
我们可以继续列出无数的示例,但仍然无法涵盖所有可用的集合方法,并且这从来都不是本文的真正目的。
需要注意的是,通过使用 Collection 类,您不仅可以获得一个方法库来简化编程工作,还可以选择一种从根本上改善代码的方法。
你会情不自禁的将你的代码结构从代码块重构简化成一行,同时减少代码的缩进,临时变量的使用和技巧性方法,另外你还可以使用链式编程方法,这让你的代码更加便于阅读和解析,此外最重要的是减少了编码工作!
查看官方文档获取更多这个迷人的类库的使用细节:https://laravel.com/docs/coll...
提示: 你还可以获取这个 Collection 类独立安装包,在使用非 laravel 项目是会非常有帮助。感谢 Tighten Co 团队做出的努力 https://github.com/tightenco/...。
感谢阅读,快乐编码!
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
The above is the detailed content of How to write code using Laravel Collections class. For more information, please follow other related articles on the PHP Chinese website!