文章转自:learnku.com/laravel/t/2…
更多文章:learnku.com/laravel/c/t…php
Laravel 集合是 Laravel 框架中一个十分有用的工具。laravel
Laravel 集合就像是在 PHP 中的数组,但会更好用。git
在这篇教程中,咱们将会体验一些集合使用时的实用技巧。github
Illuminate\Support\Collection
类了提供一个便捷的操做数组的封装。数据库
集合 Collection
类实现了部分 PHP 和 Laravel 的接口,例如:数组
你能够在这里查看其他已实现的接口。浏览器
一个集合可使用 collect()
帮助函数基于一个数组被建立 或者直接经过 Illuminate\Support\Collection
类实例化。bash
一个很是简单的使用 collect()
帮助函数的示例:闭包
$newCollection = collect([1, 2, 3, 4, 5]);
复制代码
一个更复杂的示例:app
<?php
namespace app\Http\Controllers;
use Illuminate\Support\Collection;
class TestController extends Controller
{
/**
* Create a new collection using the collect helper method.
*/
public function helperCollection()
{
$newCollection = collect([1, 2, 3, 4, 5]);
dd($newCollection);
}
/**
* Create a new collection with a Collection class instance.
*/
public function classCollection()
{
$newCollection = new Collection([1, 2, 3, 4, 5]);
dd($newCollection);
}
}
复制代码
这个帮助函数用起来要简单不少由于你再不须要实例化 Illuminate\Support\Collection
类。
我也有用到 dd()
帮助函数来在浏览器中显示集合。看起来大概会是这样子。
Laravel Eloquent ORM 也以集合的形式返回数据。
Eloquent ORM 的调用会以集合的形式返回数据
为了演示这个效果,我将初始化一个 Sqlite 数据库。
咱们将用 Laravel 框架预置的迁移文件来建立一个用户表,而后填充10条数据到用户表中。
/**
* 从用户表获取用户列表
*/
public function getUsers()
{
$users = User::all();
dd($users);
}
复制代码
该控制器方法会返回一个以下显示的全部用户的 Laravel 集合。
你能够经过箭头符号便捷的访问集合属性。至于实例,想要获取 $users
集合的第一个用户的名字,咱们能够这样作。
/**
* 获取第一个用户的名字
*/
public function firstUser()
{
$user = User::first();
dd($user->name);
}
复制代码
咱们将会使用一些最有用的集合操做技巧,你必定会以为很好用。
在接下来的几个章节中,我将会用到下面这套用户表的数据以及一些自定义的集合来达到演示的目的。虽然咱们这里是手动建立,但使用 Laravel 的模型工厂来建立也是能够的。
Array
(
[0] => Array
(
[id] => 1
[name] => Chasity Tillman
[email] => qleuschke@example.org
[age] => 51
[created_at] => 2016-06-07 15:50:50
[updated_at] => 2016-06-07 15:50:50
)
...
)
复制代码
有多种方法能够在集合中查找数据。
contains
contains()
方法能够传一个单一值,或一组键 / 值对或者一个回调函数,而后它会返回一个布尔值来告知目标内容是否在集合中。
/**
* 判断键 / 值对或回调内容是否存在于集合中
*
*
* @return true or false
*/
public function contains()
{
$users = User::all();
$users->contains('name', 'Chasity Tillman');
//true
$collection = collect(['name' => 'John', 'age' => 23]);
$collection->contains('Jane');
//false
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function ($key, $value) {
return $value <= 5;
//true
});
}
复制代码
where
经过键值对的形式, 用 where 方法检索集合.
where() 方法还能够被链式调用。
/**
* 使用 where 方法找到匹配的数据
*
* 经过链式调用来增长匹配条件
*/
public function where()
{
$users = User::all();
$user = $users->where('id', 2);
// 找出 id 为 2 的用户
$user = $users->where('id', 1)
->where('age', '51')
->where('name', 'Chasity Tillman');
// 找出 user 集合中 id 为 1,年龄为 51 岁,名叫 Chasity Tillman 的用户
}
复制代码
还有一些像 where-like
这种用于检索的方法,我就不一一列举的,你们能够经过 Laravel 的官方文档查看。
能够着重看下面几个:
whereIn() - 以键值对为参数检索集合,其中值必须是组数。
search() - 在一个集合中检索值,若是有值,返回其索引,若是没有,则返回 false
。
has() - 查看键值对是否存,返回布尔值。
你可能已经猜到了,用 filter()
方法过滤。
你可能也已经想到了, filter 方法会接收一个回调函数做为参数,在回调函数中作判断的逻辑,对吗?你是这么想的吗?
/**
* 使用 filter 方法,找出全部年龄小于 35 的用户
*/
public function filter()
{
$users = User::all();
$youngsters = $users->filter(function ($value, $key) {
return $value->age < 35;
});
$youngsters->all();
// 全部年龄小于 35 的用户
}
复制代码
filter 方法会接收一个回调函数做为参数,回调函数的参数是键值对,具体筛选的逻辑写在函数里面,而且会返回全部符合条件的值。
这里还用到了 all()
方法,它会返回一个集合里的全部值。
集合容许咱们可以使用两种简单的方法对数据进行排序 :-
sortBy()
- 给定数据进行升序排序sortyByDesc()
- 给定数据降序排序排序方法接受一个键或回调函数参数用于对集合进行排序。
/**
* 排序方法接受一个键或回调函数参数
* 用于对集合进行排序。
*/
public function sortData()
{
$users = User::all();
$youngestToOldest = $users->sortBy('age');
$youngestToOldest->all();
//列出以年龄升序的全部用户
$movies = collect([
[
'name' => 'Back To The Future',
'releases' => [1985, 1989, 1990]
],
[
'name' => 'Fast and Furious',
'releases' => [2001, 2003, 2006, 2009, 2011, 2013, 2015, 2017]
],
[
'name' => 'Speed',
'releases' => [1994]
]
]);
$mostReleases = $movies->sortByDesc(function ($movie, $key) {
return count($movie['releases']);
});
$mostReleases->toArray();
//列出以上映总数降序排序的电影
dd($mostReleases->values()->toArray());
/*
列出以上映总数降序排序的电影并重置键值
*/
}
复制代码
排序方法维护每一个值的键。 虽然这对您的应用程序可能很重要,但您能够经过链式 values()
方法将它们重置为默认的基于零的增量值。
像往常同样,我还使用一个将集合转换为数组的集合方法 toArray()
。
###groupBy
对集合进行分组有助于理解您的数据。 groupBy 方法接受键或回调函数,并根据键值或返回的回调值返回分组集合。
/**
* groupBy 返回基于键或回调函数分组的数据
* 逻辑
*/
public function grouping()
{
$movies = collect([
['name' => 'Back To the Future', 'genre' => 'scifi', 'rating' => 8],
['name' => 'The Matrix', 'genre' => 'fantasy', 'rating' => 9],
['name' => 'The Croods', 'genre' => 'animation', 'rating' => 8],
['name' => 'Zootopia', 'genre' => 'animation', 'rating' => 4],
['name' => 'The Jungle Book', 'genre' => 'fantasy', 'rating' => 5],
]);
$genre = $movies->groupBy('genre');
/*
[
"scifi" => [
["name" => "Back To the Future", "genre" => "scifi", "rating" => 8,],
],
"fantasy" => [
["name" => "The Matrix", "genre" => "fantasy", "rating" => 9,],
["name" => "The Jungle Book", "genre" => "fantasy", "rating" => 5, ],
],
"animation" => [
["name" => "The Croods", "genre" => "animation", "rating" => 8,],
["name" => "Zootopia", "genre" => "animation", "rating" => 4, ],
],
]
*/
$rating = $movies->groupBy(function ($movie, $key) {
return $movie['rating'];
});
/*
[
8 => [
["name" => "Back To the Future", "genre" => "scifi", "rating" => 8,],
["name" => "The Croods", "genre" => "animation", "rating" => 8,],
],
9 => [
["name" => "The Matrix", "genre" => "fantasy", "rating" => 9,],
],
4 => [
["name" => "Zootopia","genre" => "animation", "rating" => 4,],
],
5 => [
["name" => "The Jungle Book","genre" => "fantasy","rating" => 5,],
],
]
*/
}
复制代码
给定一组数据,而后是一个集合,您可能但愿获得它的一部分。 这多是:
集合操做帮助咱们使用少许的方法完成这些操做。
take
take 方法接受一个整数值并返回指定的项数。给定一个负数,take()
返回集合末尾的指定项数。
/**
* take 方法返回集合中的 n 个项数。
* 给定 -n ,返回最后 n 个项数
*/
public function takeMe()
{
$list = collect([
'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
]);
//获取前两个名字
$firstTwo = $list->take(2);
//['Albert', 'Ben']
//获取最后两个名字
$lastTwo = $list->take(-2);
//['Yuri', 'Zane']
}
复制代码
chunk
chunk 方法将集合分割成大小为 n 的较小集合。
/**
* Chunk(n) 返回大小为 n 的较小集合,每一个都来自原始集合
*
*/
public function chunkMe()
{
$list = collect([
'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
]);
$chunks = $list->chunk(3);
$chunks->toArray();
/*
[
["Albert", "Ben", "Charles",],
[3 => "Dan", 4 => "Eric", 5 => "Xavier",],
[6 => "Yuri", 7 => "Zane",],
]
*/
}
复制代码
这里有不少方法能够达到效果。
当你传递数据到 blade 页面时,你能够将他分块以一次得到 n 行数据,例如,将每 3 个名字装进一行。
@foreach($list->chunk(3) as $names)
<div class="row">
@foreach($names as $name)
{{ $name }}
@endforeach
</div>
@endforeach
复制代码
你也可使用 collapse()
方法将更新的集合组转成一个大的集合,来反转 chunk
方法,请查看此 here.
map
map 方法会遍历集合,将每一个元素传入一个闭包函数,该闭包函数的返回值将替换原来的元素值。
咱们建立一个由名字组成的集合,并使用 map 方法返回一个由对应名字长度组成的集合。
/**
* map function iterates a collection through a callback
* function and performs an operation on each value.
*/
public function mapMe()
{
$names = collect([
'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
]);
$lengths = $names->map(function ($name, $key) {
return strlen($name);
});
$lengths->toArray();
//[6, 3, 7, 3, 4, 6, 4, 4,]
}
复制代码
transform
虽然 map 方法建立了一个新的集合,但有时候你可能想去修改原始的集合内容。transform 提供了一个回调方法,并对同一个集合进行操做。
由于转换不会产生新的集合,因此你无需把它赋给新的值。
/**
* Transform 操做原始的集合。
*/
public function transformMe()
{
$names = collect([
'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
]);
$names->transform(function ($name, $key) {
return strlen($name);
});
$names->toArray();
//[6, 3, 7, 3, 4, 6, 4, 4,]
}
复制代码
reduce
不一样于 map 和 transform 方法,reduce 方法返回单个值。他将每次迭代的结果传给下一次迭代。
例如,为了获取一个集合中全部整数的和,reduce 会传递后续数字的总和,并迭代的将结果添加到下一个数字。
/**
* 获取一个集合中全部数字的和
*/
public function reduceMe()
{
$numbers = collect([
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
]);
$sum = $numbers->reduce(function ($sum, $number) {
return $sum + $number;
});
//55
}
复制代码
each
each 方法经过回调函数传递每一个数据项。
关于 each 方法最有趣的部分是,你能够简单的在回调函数中返回 false 来跳出循环。
/**
*打印小于等于五的一列数字
*
*/
public function eachMethod()
{
$numbers = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$smallNumbers = $numbers->each(function ($num, $key) {
if ($num > 5) {
return false;
}
echo $num .", ";
});
//1, 2, 3, 4, 5,
}
复制代码
every
every 方法建立一个由集合中每第 n 个元素组成的新集合。
Laravel 提供了对集合论的支持,这意味着咱们能够对两个不一样集合取交集、并集等操做。
union
union
方法将给定的数组添加到集合。若是给定的数组含有与原集合同样的键,则原集合的值不会被改变:
/**
* add array values to a collection using union
*/
public function union()
{
$coolPeople = collect([
1 => 'John', 2 => 'James', 3 => 'Jack'
]);
$allCoolPeople = $coolPeople->union([
4 => 'Sarah', 1 => 'Susan', 5 =>'Seyi'
]);
$allCoolPeople->all();
/*
[
1 => "John", 2 => "James", 3 => "Jack", 4 => "Sarah", 5 => "Seyi",
]
*/
}
复制代码
intersect
intersect() 方法接收一个数组或集合做为参数,该方法会将集合中那些不包含在传入参数的元素移除。
/**
* Return a list of very cool people in collection that
* are in the given array
*/
public function intersect()
{
$coolPeople = collect([
1 => 'John', 2 => 'James', 3 => 'Jack'
]);
$veryCoolPeople = $coolPeople->intersect(['Sarah', 'John', 'James']);
$veryCoolPeople->toArray();
//[1 => "John" 2 => "James"]
}
复制代码
能够发现, intersect 方法的返回值保留了原有的键。
我试图涵盖你可能找到你能本身找到所需的集合方法,但这仍然有太多须要学的。
最值得注意的,我留下如下内容
在 Laravel 文档 和 Laravel API 文档 上还有你能够用于操做集合的更多方法,货心你想查看一下。
要跟进本教程代码,查看 gtihub 仓库 here。随意贡献你的代码。