在通过对array进行简单的封装之后,我们有了一个可以更好适配high order function的Collection,为了避免Collection和array之间的类型转换,让Collection用起来完全就是一个原生数组,我们需要实现一些PHP interface。
如下:
<?php
/**
* collection
*/
class Collection implements ArrayAccess, Countable
{
protected $items;
public function __construct(array $items)
{
$this->items = $items;
}
public function make($items)
{
return new static($items);
}
public function map($transform)
{
return new static(array_map($transform, $this->items));
}
public function filter($criteria)
{
return new static(array_filter($criteria, $this->items));
}
public function offsetExists($offset): boolean
{
return array_key_exists($this->items, $offset);
}
public function offsetGet($offset)
{
return $this->items[$offset];
}
public function offsetSet($offset, $value)
{
if ($offset === null) {
$this->items[] = $value;
} else {
$this->items[$offset] = $value;
}
}
public function offsetUnset($offset)
{
unset($this->items[$offset]);
}
public function count()
{
return count($this->items);
}
public function getIterator()
{
return new ArrayIterator($this->items);
}
}
$hellos = [
[
'title' => 'hello',
'content' => 'this is hello world!',
],
[
'title' => 'hello2',
'content' => 'this is hello2 world!',
],
[
'title' => 'hello3',
'content' => 'this is hello3 world!',
],
];
$titleCollection = Collection::make($hellos)->map(
function ($episode) {
return $episode['title'];
});
var_dump($titleCollection);
$coll = Collection::make($hellos);
$coll[] = [
'title' => 'Test3',
'content' => 0,
];
var_dump($coll); // Now we have three episodes
unset($coll[0]);
var_dump($coll);
处理数据集合的“最佳实践”
“除了实现一个Collection class之外,永远都不要使用for循环来处理数据。”
这是我们在这个系列中,始终围绕的一个主题。无论你从任何来源获得了原始数据,当你要对它们加工处理时,你都不应该使用原始的for循环。
就如同我们已经看到过的一些场景一样:
当你逐个处理时,你需要的是each;
当你转换元素生成新的集合时,你需要的是map;
当你要对集合中的元素进行过滤时,你需要的是filter;
当你合并集合时,你需要的是merge;
当你需要去重时,你需要的是unique;
…
总之,每当你需要对数据进行加工处理的时候,你都可以采用一个或多个high order function组合起来帮你完成任务。而当你这样做之后,你的代码就会变得更加简洁、易懂并且易于测试和维护。
分类: web
标签: