Completed
Push — master ( a332d2...53b748 )
by Matthew
01:45
created

LazyCollection::reduce()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PublishingKit\Utilities\Collections;
6
7
use Countable;
8
use IteratorAggregate;
9
use ArrayIterator;
10
use JsonSerializable;
11
use Generator;
12
use Traversable;
13
use Serializable;
14
use PublishingKit\Utilities\Contracts\Collectable;
15
use PublishingKit\Utilities\Traits\Macroable;
16
17
class LazyCollection implements Collectable, Countable, IteratorAggregate, JsonSerializable, Serializable
18
{
19 1
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait PublishingKit\Utilities\Traits\Macroable requires the property $name which is not provided by PublishingKit\Utilities\Collections\LazyCollection.
Loading history...
20
21
    /**
22
     * @var callable|static
23
     */
24
    private $source;
25
26
    /**
27
     * Create a new lazy collection instance.
28
     *
29
     * @param  mixed  $source
30
     * @return void
31
     */
32 78
    public function __construct($source = null)
33
    {
34 78
        if (is_callable($source) || $source instanceof self) {
35 78
            $this->source = $source;
36 27
        } elseif (is_null($source)) {
37 3
            $this->source = static::empty();
38
        } else {
39 27
            $this->source = $this->getArrayableItems($source);
40
        }
41 78
    }
42
43
    /**
44
     * {@inheritDoc}
45
     *
46
     * @return self
47
     */
48 3
    public static function make(callable $callback): self
49
    {
50 3
        return new static($callback);
51
    }
52
53
    /**
54
     * Create a new instance with no items.
55
     *
56
     * @return static
57
     */
58 3
    public static function empty()
59
    {
60 3
        return new static([]);
61
    }
62
63
    /**
64
     * Results array of items from Collection or Arrayable.
65
     *
66
     * @param mixed  $items
67
     *
68
     * @return iterable
69
     */
70 27
    protected function getArrayableItems($items): iterable
71
    {
72 27
        if (is_array($items)) {
73 15
            return $items;
74 12
        } elseif ($items instanceof Collectable) {
75 3
            return $items->toArray();
76 9
        } elseif ($items instanceof JsonSerializable) {
77 3
            return (array) $items->jsonSerialize();
78 6
        } elseif ($items instanceof Traversable) {
79 3
            return iterator_to_array($items);
80
        }
81 3
        return (array) $items;
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     */
87 3
    public function toJson()
88
    {
89 3
        return json_encode($this->toArray());
90
    }
91
92
    /**
93
     * Get the collection of items as a plain array.
94
     *
95
     * @return iterable
96
     */
97 27
    public function toArray(): iterable
98
    {
99 18
        return $this->map(function ($value) /* @return mixed */ {
100 27
            return $value instanceof Collectable ? $value->toArray() : $value;
101 27
        })->all();
102
    }
103
104
    /**
105
     * {@inheritDoc}
106
     *
107
     * @return iterable
108
     */
109 39
    public function all(): iterable
110
    {
111 39
        if (is_array($this->source)) {
112 6
            return $this->source;
113
        }
114 33
        return iterator_to_array($this->getIterator());
115
    }
116
117
    /**
118
     * {@inheritDoc}
119
     */
120 27
    public function map(callable $callback)
121
    {
122 18
        return new static(function () use ($callback) {
123 27
            foreach ($this as $key => $value) {
124 27
                yield $key => $callback($value, $key);
125
            }
126 27
        });
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132 9
    public function filter(callable $callback = null)
133
    {
134 9
        if (is_null($callback)) {
135 2
            $callback = function ($value): bool {
136 3
                return (bool) $value;
137 3
            };
138
        }
139 6
        return new static(function () use ($callback) {
140 9
            foreach ($this as $key => $value) {
141 9
                if ($callback($value, $key)) {
142 9
                    yield $key => $value;
143
                }
144
            }
145 9
        });
146
    }
147
148
    /**
149
     * {@inheritDoc}
150
     */
151 3
    public function reject(callable $callback)
152
    {
153 2
        return $this->filter(function ($item) use ($callback) {
154 3
            return !$callback($item);
155 3
        });
156
    }
157
158
    /**
159
     * {@inheritDoc}
160
     */
161 3
    public function reduce(callable $callback, $initial = 0)
162
    {
163 3
        $result = $initial;
164 3
        foreach ($this as $value) {
165 3
            $result = $callback($result, $value);
166
        }
167 3
        return $result;
168
    }
169
170
    /**
171
     * {@inheritDoc}
172
     */
173 3
    public function pluck($name)
174
    {
175 2
        return $this->map(function ($item) use ($name) {
176 3
            return $item[$name];
177 3
        });
178
    }
179
180
    /**
181
     * {@inheritDoc}
182
     */
183 3
    public function each(callable $callback)
184
    {
185 3
        foreach ($this->source as $item) {
186 3
            $callback($item);
187
        }
188 3
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193 3
    public function count()
194
    {
195 3
        return iterator_count($this->getIterator());
196
    }
197
198
    /**
199
     * {@inheritDoc}
200
     */
201 42
    public function getIterator()
202
    {
203 42
        return $this->makeIterator($this->source);
204
    }
205
206
    /**
207
     * {@inheritDoc}
208
     */
209 3
    public function jsonSerialize()
210
    {
211 3
        return json_encode($this->toArray());
212
    }
213
214
    /**
215
     * Make an iterator from the given source.
216
     *
217
     * @param  mixed  $source
218
     * @return \Traversable
219
     */
220 42
    protected function makeIterator($source)
221
    {
222 42
        if (is_array($source)) {
223 6
            return new ArrayIterator($source);
224
        }
225 42
        return $source();
226
    }
227
228
    /**
229
     * {@inheritDoc}
230
     */
231 3
    public function serialize()
232
    {
233 3
        return serialize($this->toArray());
234
    }
235
236
    /**
237
     * {@inheritDoc}
238
     */
239 3
    public function unserialize($serialized)
240
    {
241 3
        $this->source = unserialize($serialized);
242 3
    }
243
244 3
    public function __debugInfo()
245
    {
246 3
        return $this->toArray();
247
    }
248
}
249