Laravel 编码技巧 - 集合
使用自定义回调函数对集合进行 groupBy
如果您想按照数据库中不是直接列出的某些条件对结果进行分组,可以通过提供一个闭包函数来实现。
例如,如果您想按注册日期对用户进行分组,可以使用以下代码:
$users = User::all()->groupBy(function($item) {
return $item->created_at->format('Y-m-d');
});
⚠️ 注意:这是在 Collection 类上执行的,因此是在从数据库获取结果之后进行的操作。
Laravel Scopes 可以使用“Higher Order”或Where方法进行组合。
以下是来自文档的示例。
在此之前:
User::popular()->orWhere(function (Builder $query) {
$query->active();
})->get()
之后:
User::popular()->orWhere->active()->get();
多个集合方法连续使用
如果您使用->all()
或->get()
查询所有结果,然后可以对相同的结果执行各种集合操作,而不会每次都查询数据库。
$users = User::all();
echo 'Max ID: ' . $users->max('id');
echo 'Average age: ' . $users->avg('age');
echo 'Total budget: ' . $users->sum('budget');
在分页情况下计算总和
当您只有分页的集合时,如何计算所有记录的总和?在分页之前进行计算,但使用相同的查询。
// 如何在分页的情况下获取 post_views 的总和?
$posts = Post::paginate(10);
// 这只会针对第一页,而不是所有的帖子
$sum = $posts->sum('post_views');
// 使用查询构建器实现
$query = Post::query();
// 计算总和
$sum = $query->sum('post_views');
// 然后从同一查询进行分页
$posts = $query->paginate(10);
在foreach
循环中使用分页的序列号
我们可以在分页中使用foreach
集合项的索引作为序列号(SL)。
<!-- 在表头中添加序列号列 -->
<th>Serial</th>
<!-- 在foreach循环中使用序列号 -->
@foreach ($products as $product)
<tr>
<td>{{ $loop->index + $products->firstItem() }}</td>
<!-- 其他列的内容 -->
...
</tr>
@endforeach
通过在循环中使用 $loop->index + $products->firstItem()
,您可以在分页中正确计算序列号,解决了在下一页(例如,?page=2&...
)中索引计数连续的问题。
高阶集合信息
集合还支持“higher order messages”(高阶消息),这是对集合执行常见操作的快捷方式。以下示例计算了在一份优惠中每组产品的价格总和。
$offer = [
'name' => 'offer1',
'lines' => [
['group' => 1, 'price' => 10],
['group' => 1, 'price' => 20],
['group' => 2, 'price' => 30],
['group' => 2, 'price' => 40],
['group' => 3, 'price' => 50],
['group' => 3, 'price' => 60]
]
];
$totalPerGroup = collect($offer['lines'])->groupBy->group->map->sum('price');
获取一个现有的键,如果不存在,则插入一个值并返回该值
在 Laravel 8.81 中,引入了 getOrPut
方法到集合(Collections),简化了一种情况,即您要么获取现有的键,要么在键不存在时插入一个值并返回该值。
$key = 'name';
// 仍然有效的方式
if ($this->collection->has($key) === false) {
$this->collection->put($key, ...);
}
return $this->collection->get($key);
// 使用 `getOrPut()` 方法与闭包
return $this->collection->getOrPut($key, fn() => ...);
// 或传递一个固定的值
return $this->collection->getOrPut($key, $value='teacoders');
静态时间法
times
方法是集合(Collection)类的静态方法,通过调用指定次数的闭包来创建一个新的集合。
Collection::times(7, function ($number) {
return now()->addDays($number)->format('d-m-Y');
});
// 输出:[01-04-2022, 02-04-2022, ..., 07-04-2022]
请登录后再评论