- 集合 collection
- 基本使用
- 静态方法 make 创建集合
- 集合支持迭代器
- 集合可统计
- 集合数据支持实现 \Leevel\Support\IArray 的对象
- 集合数据支持实现 \Leevel\Support\IJson 的对象
- 集合数据支持实现 \JsonSerializable 的对象
- 集合数据支持普通数据转化为数组
- 集合数据支持 \stdClass 的对象
- 集合数据支持类型验证
- 集合数据支持类型验证不符合规则示例
- each 集合数据遍历元素项
- each 集合数据遍历元素项支持中断
- toJson 集合数据支持 JSON 输出
- toJson 集合数据支持 JSON 输出默认不要编码 Unicode
- toJson 集合数据支持 JSON 输出
- __toString 集合数据可以转化为字符串
集合 collection
Testing Is Documentation
tests/Collection/CollectionTest.php
集合 collection
提供了一些实用方法,数据库查询的数据列表也会转换为集合数据类型。
Uses
<?php
use JsonSerializable;
use Leevel\Collection\Collection;
use Leevel\Support\IArray;
use Leevel\Support\IJson;
use stdClass;
基本使用
集合实现了 \IteratorAggregate
可以像普通数组一样遍历,也实现了 \ArrayAccess
接口,可以当做普通数组一样使用。
public function testBaseUse(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
foreach ($collection as $key => $val) {
switch ($key) {
case 0:
$this->assertSame($val, 'hello');
break;
case 1:
$this->assertSame($val, 'world');
break;
case 2:
$this->assertSame($val, 'foo');
break;
case 3:
$this->assertSame($val, 'bar');
break;
}
}
$this->assertSame($collection[0], 'hello');
$this->assertSame($collection[1], 'world');
$this->assertSame($collection[2], 'foo');
$this->assertSame($collection[3], 'bar');
$this->assertTrue(isset($collection[0]));
$this->assertTrue(isset($collection[1]));
$this->assertTrue(isset($collection[2]));
$this->assertTrue(isset($collection[3]));
$this->assertFalse(isset($collection[4]));
}
静态方法 make 创建集合
可以使用 make
方法创建一个集合对象。
public function testMake(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = Collection::make($data);
foreach ($collection as $key => $val) {
switch ($key) {
case 0:
$this->assertSame($val, 'hello');
break;
case 1:
$this->assertSame($val, 'world');
break;
case 2:
$this->assertSame($val, 'foo');
break;
case 3:
$this->assertSame($val, 'bar');
break;
}
}
$this->assertSame($collection[0], 'hello');
$this->assertSame($collection[1], 'world');
$this->assertSame($collection[2], 'foo');
$this->assertSame($collection[3], 'bar');
$this->assertTrue(isset($collection[0]));
$this->assertTrue(isset($collection[1]));
$this->assertTrue(isset($collection[2]));
$this->assertTrue(isset($collection[3]));
$this->assertFalse(isset($collection[4]));
}
集合支持迭代器
集合 collection
是一个标准的迭代器,支持迭代器的用法。
public function testIterator(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
$this->assertSame('hello', $collection->current());
$this->assertSame(0, $collection->key());
$this->assertNull($collection->next());
$this->assertSame('world', $collection->current());
$this->assertSame(1, $collection->key());
$this->assertNull($collection->next());
$this->assertNull($collection->next());
$this->assertSame('bar', $collection->current());
$this->assertSame(3, $collection->key());
$collection->next();
$this->assertFalse($collection->current());
$this->assertNull($collection->key());
$collection->rewind();
$this->assertSame(0, $collection->key());
$this->assertSame('hello', $collection->current());
}
集合可统计
集合实现了 \Countable
可以像普通数组一样统计元素的个数。
public function testCountable(): void
{
$data = [
'hello', 'world', 'foo', 'bar',
];
$collection = new Collection($data);
$this->assertCount(4, $collection);
}
集合数据支持实现 \Leevel\Support\IArray 的对象
对象实现了 \Leevel\Support\IArray
可以转化为集合数据。
例子
namespace Tests\Collection;
class TestArray implements IArray
{
public function toArray(): array
{
return [
'hello',
'world',
];
}
}
实现了
\Leevel\Support\IArray
的对象的方法toArray
返回集合的数据。
public function testGetArrayElements2(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestArray());
$this->assertSame($collection->toArray(), $data);
}
集合数据支持实现 \Leevel\Support\IJson 的对象
对象实现了 \Leevel\Support\IJson
可以转化为集合数据。
例子
namespace Tests\Collection;
class TestJson implements IJson
{
public function toJson(?int $option = null): string
{
if (null === $option) {
$option = JSON_UNESCAPED_UNICODE;
}
return json_encode([
'hello',
'world',
], $option);
}
}
实现了
\Leevel\Support\IJson
的对象的方法toJson
返回集合的数据。
public function testGetArrayElements3(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestJson());
$this->assertSame($collection->toArray(), $data);
}
集合数据支持实现 \JsonSerializable 的对象
对象实现了 \JsonSerializable
可以转化为集合数据。
例子
namespace Tests\Collection;
class TestJsonSerializable implements JsonSerializable
{
public function jsonSerialize()
{
return [
'hello',
'world',
];
}
}
实现了
\JsonSerializable
的对象的方法jsonSerialize
返回集合的数据。
public function testGetArrayElements4(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection(new TestJsonSerializable());
$this->assertSame($collection->toArray(), $data);
}
集合数据支持普通数据转化为数组
public function testGetArrayElements5(): void
{
$data = [
'hello',
];
$collection = new Collection('hello');
$this->assertSame($collection->toArray(), $data);
}
集合数据支持 \stdClass 的对象
对象为 \stdClass
可以转化为集合数据。
\stdClass
的对象返回转化为数组作为集合的数据。
public function testGetArrayElementsWithStdClass(): void
{
$data = [
'hello' => 'world',
'foo' => 'bar',
];
$std = new stdClass();
$std->hello = 'world';
$std->foo = 'bar';
$collection = new Collection($std);
$this->assertSame($collection->toArray(), $data);
}
集合数据支持类型验证
比如下面的数据类型为 string
,只有字符串类型才能加入集合。
public function testTypeValidate(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data, ['string']);
$this->assertSame($collection->toArray(), $data);
$this->assertSame(['string'], $collection->getType());
}
集合数据支持类型验证不符合规则示例
比如下面的数据类型为 int
,字符串类型就会抛出异常。
public function testTypeValidateException(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(
'Collection type int validation failed.'
);
$data = [
'hello',
'world',
];
new Collection($data, ['int']);
}
each 集合数据遍历元素项
使用闭包进行遍历,闭包的第一个参数为元素值,第二为元素键。
public function testEach(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$i = 0;
$collection->each(function ($item, $key) use (&$i) {
$this->assertSame($i, $key);
if (0 === $i) {
$this->assertSame($item, 'hello');
} else {
$this->assertSame($item, 'world');
}
$i++;
});
}
each 集合数据遍历元素项支持中断
遍历元素项的时候返回 false
将会中断后续遍历操作。
public function testEachAndBreak(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$i = 0;
$collection->each(function ($item, $key) use (&$i) {
$this->assertSame($i, $key);
if (0 === $i) {
$this->assertSame($item, 'hello');
return false;
}
$i++;
});
$this->assertSame($i, 0);
}
toJson 集合数据支持 JSON 输出
集合实现了 \Leevel\Support\IJson
接口,可以通过方法 toJson
输出 JSON 字符串。
public function testToJson(): void
{
$data = [
'hello',
'world',
];
$collection = new Collection($data);
$data = '["hello","world"]';
$this->assertSame($data, $collection->toJson());
}
toJson 集合数据支持 JSON 输出默认不要编码 Unicode
JSON_UNESCAPED_UNICODE 可以让有中文的 JSON 字符串更加友好地输出。
json_encode('中文', JSON_UNESCAPED_UNICODE);
public function testToJsonWithCn(): void
{
$data = [
'我',
'成都',
];
$collection = new Collection($data);
$data = '["我","成都"]';
$this->assertSame($data, $collection->toJson());
}
toJson 集合数据支持 JSON 输出
集合实现了 \JsonSerializable
接口,可以通过方法 toJson
输出 JSON 字符串。
public function testJsonSerialize(): void
{
$std = new stdClass();
$std->hello = 'world';
$std->foo = 'bar';
$data = [
new TestJsonSerializable(),
new TestArray(),
new TestJson(),
$std,
'foo',
'bar',
];
$collection = new Collection($data);
$data = <<<'eot'
[
[
"hello",
"world"
],
[
"hello",
"world"
],
[
"hello",
"world"
],
{
"hello": "world",
"foo": "bar"
},
"foo",
"bar"
]
eot;
$this->assertSame(
$data,
$this->varJson(
$collection->jsonSerialize()
)
);
}
__toString 集合数据可以转化为字符串
集合实现了 __toString
方法,可以强制转化为字符串。
public function testGetSetString(): void
{
$data = [
'hello' => 'world',
'foo' => 'bar',
];
$collection = new Collection($data);
$this->assertSame($collection->hello, 'world');
$this->assertSame($collection->foo, 'bar');
$collection->hello = 'new world';
$collection->foo = 'new bar';
$this->assertSame($collection->hello, 'new world');
$this->assertSame($collection->foo, 'new bar');
$this->assertSame((string) $collection, '{"hello":"new world","foo":"new bar"}');
}