ArrayObject – 对数组的封装
PHP有个称作SPL的标准库,其中包含了个叫做ArrayObject的类,它能提供“像数组一 样操作类”的功能,例如
- $res = new ArrayObject(array(10, 20, 30, 40));foreach ($res as $v) {
- echo "$vn";}
ArrayObject是个内置的类,所以你可以像其他类类操作一样封装它。
Arr - 包上糖衣
既然我们已经有了ArrayObject以及闭包这些特性,我们就可以开始尝试封装它:
- class Arr extends ArrayObject
- {
- static function make($array)
- {
- return new self($array);
- } function map($func)
- {
- $res = new self();
- foreach ($this as $k => $v)
- {
- $res[$k] = $func($k, $v);
- }
- return $res;
- }
- function filter($func)
- {
- $res = new self();
- foreach ($this as $k => $v)
- {
- if ($func($k, $v))
- {
- $res[$k] = $v;
- }
- }
- return $res;
- }
- }
好了,万事俱备。下面重写的PHP代码就可以解决上面提到的问题,并且看起来语法上“差 不多”了:
- $res = Arr::make($nums)
- ->filter(function($k, $v) { return $v > 15; })
- ->map(function($k, $v) { return $v * 2; });
上面的代码与传统方式有何不同呢?首先,它们可以递归并形成作用链式的调用,因此可以 添加更多的类似操作。同时,可以通过回调的两个参数分别操作数组的键以及值其项 - $k 对应键以及 $v 对应值 。这使得我们可以在闭包中使用键值,这在传统的PHP函数 array_fliter中是无法实现的。
另外个带来的额外好处就是更加一致API调用。使用传统的 PHP 函数操作,它们有可能第一个参数是个闭包,或者是个数组,抑或是多个数组…总之谁知道呢?这里是 Arr 类的完整源代码,还包含了其他有用的函数类似 reduce 以及 walk),其实它 们的实现其实方式和代码类似。
PHP之友评论