Laravel5 集合Collection
http://laravelacademy.org/post/178.html#ipt_kb_toc_178_3
1、简介
IlluminateSupportCollection
类为处理数组数据提供了平滑、方便的封装。例如,查看下面的代码,我们使用帮助函数collect
创建一个新的集合实例,为每一个元素运行strtoupper
函数,然后移除所有空元素:
$collection = collect(["taylor", "abigail", null])->map(function ($name) { return strtoupper($name); })->reject(function ($name) { return empty($name); });
正如你所看到的,Collection
类允许你使用方法链对底层数组执行匹配和减少操作,通常,没个Collection
方法都会返回一个新的Collection
实例。
2、创建集合
正如上面所提到的,帮助函数collect
为给定数组返回一个新的IlluminateSupportCollection
实例,所以,创建集合很简单:
$collection = collect([1, 2, 3]);
默认情况下,Eloquent模型的集合总是返回Collection
实例,此外,不管是在何处,只要方法都可以自由使用Collection
类。
3、集合方法列表
本文档接下来的部分我们将会讨论Collection
类上每一个有效的方法,所有这些方法都可以以方法链的方式平滑的操作底层数组。此外,几乎每个方法返回一个新的Collection
实例,允许你在必要的时候保持原来的集合备份。
all()
all
方法简单返回集合表示的底层数组:
collect([1, 2, 3])->all(); // [1, 2, 3]
chunk()
chunk
方法将一个集合分割成多个小尺寸的小集合:
$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->toArray(); // [[1, 2, 3, 4], [5, 6, 7]]
当处理栅栏系统如Bootstrap时该方法在视图中尤其有用,建设你有一个想要显示在栅栏中的Eloquent模型集合:
@foreach ($products->chunk(3) as $chunk) <div class="row"> @foreach ($chunk as $product) <div class="col-xs-4">{{ $product->name }}</div> @endforeach </div> @endforeach
collapse()
collapse
方法将一个多维数组集合收缩成一个一维数组:
$collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); $collapsed = $collection->collapse(); $collapsed->all(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
contains()
contains
方法判断集合是否包含一个给定项:
$collection = collect(["name" => "Desk", "price" => 100]); $collection->contains("Desk"); // true $collection->contains("New York"); // false
你还可以传递一个键值对到contains
方法,这将会判断给定键值对是否存在于集合中:
$collection = collect([ ["product" => "Desk", "price" => 200], ["product" => "Chair", "price" => 100], ]); $collection->contains("product", "Bookcase"); // false
最后,你还可以传递一个回调到contains
方法来执行自己的真实测试:
$collection = collect([1, 2, 3, 4, 5]); $collection->contains(function ($key, $value) { return $value > 5; }); // false
count()
count
方法返回集合中所有项的数目:
$collection = collect([1, 2, 3, 4]); $collection->count(); // 4
diff()
diff
方法将集合和另一个集合或原生PHP数组作比较:
$collection = collect([1, 2, 3, 4, 5]); $diff = $collection->diff([2, 4, 6, 8]); $diff->all(); // [1, 3, 5]
each()
each
方法迭代集合中的数据项并传递每个数据项到给定回调:
$collection = $collection->each(function ($item, $key) { // });
回调返回false
将会终止循环:
$collection = $collection->each(function ($item, $key) { if (/* some condition */) { return false; } });
filter()
filter
方法通过给定回调过滤集合,只有通过给定测试的数据项才会保留下来:
$collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function ($item) { return $item > 2; }); $filtered->all(); // [3, 4]
和filter
相反的方法是reject
。
first()
first
方法返回通过测试集合的第一个元素:
collect([1, 2, 3, 4])->first(function ($key, $value) { return $value > 2; }); // 3
你还可以调用不带参数的first
方法来获取集合的第一个元素,如果集合是空的,返回null:
collect([1, 2, 3, 4])->first(); // 1
flatten()
flatten
方法将多维度的集合变成一维的:
$collection = collect(["name" => "taylor", "languages" => ["php", "javascript"]]); $flattened = $collection->flatten(); $flattened->all(); // ["taylor", "php", "javascript"];
flip()
flip
方法将集合的键值做交换:
$collection = collect(["name" => "taylor", "framework" => "laravel"]); $flipped = $collection->flip(); $flipped->all(); // ["taylor" => "name", "laravel" => "framework"]
forget()
forget
方法通过键从集合中移除数据项:
$collection = collect(["name" => "taylor", "framework" => "laravel"]); $collection->forget("name"); $collection->all(); // [framework" => "laravel"]
注意:不同于大多数的集合方法,forget
不返回新的修改过的集合;它只修改所调用的集合。
forPage()
forPage
方法返回新的包含给定页数数据项的集合:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9])->forPage(2, 3); $collection->all(); // [4, 5, 6]
该方法需要传入页数和每页显示数目参数。
get()
get
方法返回给定键的数据项,如果不存在,返回null:
$collection = collect(["name" => "taylor", "framework" => "laravel"]); $value = $collection->get("name"); // taylor
你可以选择传递默认值作为第二个参数:
$collection = collect(["name" => "taylor", "framework" => "laravel"]); $value = $collection->get("foo", "default-value"); // default-value
你甚至可以传递回调作为默认值,如果给定键不存在的话回调的结果将会返回:
$collection->get("email", function () { return "default-value";}); // default-value
groupBy()
groupBy
方法通过给定键分组集合数据项:
$collection = collect([ ["account_id" => "account-x10", "product" => "Chair"], ["account_id" => "account-x10", "product" => "Bookcase"], ["account_id" => "account-x11", "product" => "Desk"], ]); $grouped = $collection->groupBy("account_id"); $grouped->toArray(); /* [ "account-x10" => [ ["account_id" => "account-x10", "product" => "Chair"], ["account_id" => "account-x10", "product" => "Bookcase"], ], "account-x11" => [ ["account_id" => "account-x11", "product" => "Desk"], ], ] */
除了传递字符串key,还可以传递一个回调,回调应该返回分组后的值:
$grouped = $collection->groupBy(function ($item, $key) { return substr($item["account_id"], -3); }); $grouped->toArray(); /* [ "x10" => [ ["account_id" => "account-x10", "product" => "Chair"], ["account_id" => "account-x10", "product" => "Bookcase"], ], "x11" => [ ["account_id" => "account-x11", "product" => "Desk"], ], ] */
has()
has
方法判断给定键是否在集合中存在:
$collection = collect(["account_id" => 1, "product" => "Desk"]);
$collection->has("email");
// false
implode()
implode
方法连接集合中的数据项。其参数取决于集合中数据项的类型。
如果集合包含数组或对象,应该传递你想要连接的属性键,以及你想要放在值之间的 “粘合”字符串:
$collection = collect([
["account_id" => 1, "product" => "Desk"],
["account_id" => 2, "product" => "Chair"],
]);
$collection->implode("product", ", ");
// Desk, Chair
如果集合包含简单的字符串或数值,只需要传递“粘合”字符串作为唯一参数到该方法:
collect([1, 2, 3, 4, 5])->implode("-");
// "1-2-3-4-5"
intersect()
intersect
方法返回两个集合的交集:
$collection = collect(["Desk", "Sofa", "Chair"]);
$intersect = $collection->intersect(["Desk", "Chair", "Bookcase"]);
$intersect->all();
// [0 => "Desk", 2 => "Chair"]
正如你所看到的,结果集合只保持原来集合的键。
isEmpty()
如果集合为空的话isEmpty
方法返回true
;否则返回false
:
collect([])->isEmpty();
// true
keyBy()
将指定键的值作为集合的键:
$collection = collect([
["product_id" => "prod-100", "name" => "desk"],
["product_id" => "prod-200", "name" => "chair"],
]);
$keyed = $collection->keyBy("product_id");
$keyed->all();
/*
[
"prod-100" => ["product_id" => "prod-100", "name" => "Desk"],
"prod-200" => ["product_id" => "prod-200", "name" => "Chair"],
]
*/
如果多个数据项有同一个键,只有最后一个会出现在新的集合中。
你可以传递自己的回调,将会返回经过处理的键的值作为新的键:
$keyed = $collection->keyBy(function ($item) {
return strtoupper($item["product_id"]);
});
$keyed->all();
/*
[
"PROD-100" => ["product_id" => "prod-100", "name" => "Desk"],
"PROD-200" => ["product_id" => "prod-200", "name" => "Chair"],
]
*/
keys()
keys
方法返回所有集合的键:
$collection = collect([
"prod-100" => ["product_id" => "prod-100", "name" => "Desk"],
"prod-200" => ["product_id" => "prod-200", "name" => "Chair"],
]);
$keys = $collection->keys();
$keys->all();
// ["prod-100", "prod-200"]
last()
last
方法返回通过测试的集合的最后一个元素:
collect([1, 2, 3, 4])->last(function ($key, $value) {
return $value < 3;
});
// 2
还可以调用无参的last
方法来获取集合的最后一个元素。如果集合为空。返回null:
collect([1, 2, 3, 4])->last();
// 4
map()
map
方法遍历集合并传递每个值给给定回调。该回调可以修改数据项并返回,从而生成一个新的经过修改的集合:
$collection = collect([1, 2, 3, 4, 5]);
$multiplied = $collection->map(function ($item, $key) {
return $item * 2;
});
$multiplied->all();
// [2, 4, 6, 8, 10]
注意:和大多数集合方法一样,map
返回新的集合实例;它并不修改所调用的实例。如果你想要改变原来的集合,使用
方法。transform
merge()
merge
方法合并给定数组到集合。该数组中的任何字符串键匹配集合中的字符串键的将会重写集合中的值:
$collection = collect(["product_id" => 1, "name" => "Desk"]);
$merged = $collection->merge(["price" => 100, "discount" => false]);
$merged->all();
// ["product_id" => 1, "name" => "Desk", "price" => 100, "discount" => false]
如果给定数组的键是数字,数组的值将会附加到集合后面:
$collection = collect(["Desk", "Chair"]);
$merged = $collection->merge(["Bookcase", "Door"]);
$merged->all();
// ["Desk", "Chair", "Bookcase", "Door"]