在通过对array进行简单的封装之后,我们有了一个可以更好适配high order function的Collection,为了避免Collection和array之间的类型转换,让Collection用起来完全就是一个原生数组,我们需要实现一些PHP interface。
如下:

  1. <?php
  2. /**
  3. * collection
  4. */
  5. class Collection implements ArrayAccess, Countable
  6. {
  7. protected $items;
  8. public function __construct(array $items)
  9. {
  10. $this->items = $items;
  11. }
  12. public function make($items)
  13. {
  14. return new static($items);
  15. }
  16. public function map($transform)
  17. {
  18. return new static(array_map($transform, $this->items));
  19. }
  20. public function filter($criteria)
  21. {
  22. return new static(array_filter($criteria, $this->items));
  23. }
  24. public function offsetExists($offset): boolean
  25. {
  26. return array_key_exists($this->items, $offset);
  27. }
  28. public function offsetGet($offset)
  29. {
  30. return $this->items[$offset];
  31. }
  32. public function offsetSet($offset, $value)
  33. {
  34. if ($offset === null) {
  35. $this->items[] = $value;
  36. } else {
  37. $this->items[$offset] = $value;
  38. }
  39. }
  40. public function offsetUnset($offset)
  41. {
  42. unset($this->items[$offset]);
  43. }
  44. public function count()
  45. {
  46. return count($this->items);
  47. }
  48. public function getIterator()
  49. {
  50. return new ArrayIterator($this->items);
  51. }
  52. }
  53. $hellos = [
  54. [
  55. 'title' => 'hello',
  56. 'content' => 'this is hello world!',
  57. ],
  58. [
  59. 'title' => 'hello2',
  60. 'content' => 'this is hello2 world!',
  61. ],
  62. [
  63. 'title' => 'hello3',
  64. 'content' => 'this is hello3 world!',
  65. ],
  66. ];
  67. $titleCollection = Collection::make($hellos)->map(
  68. function ($episode) {
  69. return $episode['title'];
  70. });
  71. var_dump($titleCollection);
  72. $coll = Collection::make($hellos);
  73. $coll[] = [
  74. 'title' => 'Test3',
  75. 'content' => 0,
  76. ];
  77. var_dump($coll); // Now we have three episodes
  78. unset($coll[0]);
  79. var_dump($coll);

处理数据集合的“最佳实践”

“除了实现一个Collection class之外,永远都不要使用for循环来处理数据。”

这是我们在这个系列中,始终围绕的一个主题。无论你从任何来源获得了原始数据,当你要对它们加工处理时,你都不应该使用原始的for循环。

就如同我们已经看到过的一些场景一样:

当你逐个处理时,你需要的是each;
当你转换元素生成新的集合时,你需要的是map;
当你要对集合中的元素进行过滤时,你需要的是filter;
当你合并集合时,你需要的是merge;
当你需要去重时,你需要的是unique;

总之,每当你需要对数据进行加工处理的时候,你都可以采用一个或多个high order function组合起来帮你完成任务。而当你这样做之后,你的代码就会变得更加简洁、易懂并且易于测试和维护。

分类: web

标签: