优雅使用 illuminate/database 包中的 Collection

或许你很抵抗使用 Laravel , 但是你没有理由不喜欢使用 illuminate/database。这是一个 ORM 的类库。我个人认为,这个类库你是否用的好,其中很重要的一点就是你是否能用好 Collection 这个数据结构,Collection 这个数据结构的源码在 Illuminate\\Database\\Eloquent\\Collection

Collection 这个数据结构有很多方法。各种方法有很多其实都是重复的。官方文档 里面有最全的示例和说明。当不了解一个函数的使用的时候,翻看官方文档是最好的选择。

我这里想介绍一些我在实际工作生活中觉得 Collection 最有用的一些方法。

首先,我把 Collection 的方法做了一下分类。

前提

这篇介绍的 illuminate/database 版本为5.6

例子中使用的 user 表的结构和数据如下:

ORM 相关

load

这里面的 load 方法是非常有用的。它的用处在于把一个 Model 关联的集合给一次性关联查询出来。结合illuminate/database 的相关 relation 是非常有用的

use App\Comment;

class User extends \Illuminate\Database\Eloquent\Model
{
protected $table = "user"; public function comments()
{
$this->hasMany(App\Comment)
}
} $users = User::all();
$users->load('comments');

find

如果你要按照主键进行查找,那么 find 方法是你最好的选择。

$users = User::all();
$user = $users->find(1);

构造类

基本我经常用的只有一个 make 方法。

make

$arr = [1,2,3];
$collection = Collection::make($arr);

提取类

pluck, unique

这两个用的非常多,比如我需要获取 user 表中 所有的 weight 值:

$users = User::all();
$weights = $users->pluck('weight')->unique();

keyBy

如果我需要获取我得到的这批数据以某个字段为key,这种很经常用在有一个非主键的唯一键的情况。

$users = User::all();
$users = $users->keyBy('name');

计算类

计算类的函数就使用非常多了,在各种逻辑中都会用到

max, min, avg, random

$users = User::all();
$maxWeight = $users->max('weight'); $minWeight = $users->min('weight'); $avgWeigth = $users->avg('weight'); $randomUser = $users->random();

判断类

contains

我认为 contains 是用来判断这个数组中是否包含最好用的方法,语义啥的都是最好的,没有之一了。

$users = User::all();
$isContain = $users->contains(function($user) {
return $user->weight > 33;
});

查找过滤类

这一类的各个函数估计有很多都重复了。基本上掌握 where 系列的语句就能满足各种查找过滤需求了。如果再复杂一点的过滤查找逻辑,就使用filter。

$users = User::all();

$overWeightUsers = $users->where('weight', '>', 33);

$firstUser = $users->first();

$firstOverWeightUser = $users->firstWhere('weight', '>', 33);

$nameOkUsers = $users->filter(function($user) {
return ucfirst($user->name) == 'Test4';
});

重组类

重组类的功能非常好用,这类方法用的好,会让你的代码优美很多。而且会享受到函数式编程的快感。

map, reduce

这两个函数的使用就是和其他函数式语言的一样。

$sumShowWeight = $users->map(function($user) {
return ['name' => $user->name, 'show_weight' => $user->weight + 10];
})->reduce(function($carry, $item) {
return $carry + $item['show_weight'];
});

我这里获取所有用户经过计算之后的 show_weight 的 sum 值,这么一句就可以搞定了。

transform

对集合内每个元素都进行操作从而重组一个新的集合:

$showUsers = $users->transform(function($user) {
return ['name' => $user->name, 'show_weight' => $user->weight + 10];
});

groupBy

groupBy也是很常用的,它不仅可以把所需要字段的唯一值获取出来,而且可以获取出每个唯一值有哪些分组。


$users = User::all();
$groupUsers = $users->groupBy('weight');

排序类

排序类一般和其他的函数一起使用。比如获取最轻的用户:

$users = User::all();
$lessWeightUser = $users->sortBy('weight')->first();

思考

illuminate/database 提供的 Collection 函数已经是非常灵活和强大了。如果一定要有一个标准判断你的代码写的好不好,那么一定是代码行数是否够少。而 Collection 使用的函数能让我们的代码行数大大压缩。全面系统思考下这些函数的使用场景是一个能让你的代码越来月优雅的方式。

参考文档

https://scotch.io/tutorials/laravel-collections-php-arrays-on-steroids

优雅使用 illuminate/database 包中的 Collection的更多相关文章

  1. 将PL/SQL代码封装在机灵的包中

    将代码封装在机灵的包中 http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13plsql-1872456.html 绝大多数基于 ...

  2. PL/SQL --> 动态SQL调用包中函数或过程

    动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句.最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量.但是对于系统自定义的包或用户自定的包 ...

  3. java中的Collection集合类

    随着1998年JDK 1.2的发布,同时新增了常用的Collections集合类,包含了Collection和Map接口.而Dictionary类是在1996年JDK 1.0发布时就已经有了.它们都可 ...

  4. Java:concurrent包下面的Collection接口框架图( CopyOnWriteArraySet, CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  5. [Illuminate\Database\QueryException] SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using pas sword: NO) (SQL: select * from information_schema.tables where table_schema = la

    [Illuminate\Database\QueryException] SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost ...

  6. 单点登录(十二)-----遇到问题-----cas启用mongodb验证方式登录后没反应-pac4j-mongo包中的MongoAuthenticatInvocationTargetException

    cas启用mongodb验证方式登录后没反应 控制台输出 2017-02-09 20:27:15,766 INFO [org.jasig.cas.authentication.MongoAuthent ...

  7. Java项目中如何扩展第三方jar包中的类?

    有些时候你对第三方得到jar包中的类并不是很满意,想根据实际情况做一些扩展.如果说第三方的jar包已经提供了一些可扩展的类,比如提供了Interceptor,Filter或者其他的类,那么使用原生的比 ...

  8. [实践]使用JarJar优雅的发布依赖包

    [实践]使用JarJar优雅的发布依赖包 打包工具: Jar Jar Links是一个Java类库重新打包工具. 可以帮助你将其它用到的java库打包并嵌入到你自己的项目jar包中.这样做的原因有: ...

  9. Java并发(6):concurrent包中的Copy-On-Write容器

    一. concurrent包介绍 在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,而当针对高质量Java多线程并发程序设计时,为防止死蹦等现象的出现,比如使用java ...

随机推荐

  1. 非阻塞式的原子性操作-CAS应用及原理

    一:问题抛出 假设在出现高并发的情况下对一个整数变量做依次递增操作,下面这两段代码是否会出现问题? 1. public class IntegerTest { private static Integ ...

  2. 最小生成数之Kruskal算法

    描述 随着小Hi拥有城市数目的增加,在之间所使用的Prim算法已经无法继续使用了--但是幸运的是,经过计算机的分析,小Hi已经筛选出了一些比较适合建造道路的路线,这个数量并没有特别的大. 所以问题变成 ...

  3. 【django基础补充之URL,视图,模版】

    一.url路由配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代 ...

  4. Dig out WeChat deleted chat messages on Android Phone

    As we know that WeChat will wipe deleted chat messages. That's why forensic guys could  not dig out ...

  5. git生成sshkey

  6. APACHE服务器出现No input file specified.的完美解决方案

    转自:http://www.upupw.net/server/n53.html 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:"No input file s ...

  7. java开发都需要学什么

    1.java基础 2.JSP+Servlet+JavaBean 环节主要 懂流程 MVC而已 别往深了研究 现 开发基本 用 模式 3.Struts+Hibernate+Spring 才 开发 主流技 ...

  8. Oracle 数据库中在使用中文模糊查询时输入中文查询不到结果的解决方法

    添加环境变量 变量名:NLS_LANG 变量值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK

  9. React Native学习(八)—— 对接七鱼客服

    本文基于React Native 0.52 Demo上传到Git了,有需要可以看看,写了新内容会上传的.Git地址 https://github.com/gingerJY/React-Native-D ...

  10. C# 内置 DateTime类详解

    C# 内置 DateTime类详解 摘抄自微软官方文档,用来方便自己查阅:网址:https://msdn.microsoft.com/zh-cn/library/system.datetime(v=v ...