1 | <?php |
||||||
2 | |||||||
3 | namespace MuCTS\Collections; |
||||||
4 | |||||||
5 | use ArrayIterator; |
||||||
6 | use Closure; |
||||||
7 | use MuCTS\Collections\Traits\EnumeratesValues; |
||||||
8 | use MuCTS\Contracts\Collections\Enumerable; |
||||||
9 | use MuCTS\Macroable\Traits\Macroable; |
||||||
10 | use IteratorAggregate; |
||||||
11 | use stdClass; |
||||||
12 | |||||||
13 | class LazyCollection implements Enumerable |
||||||
14 | { |
||||||
15 | use EnumeratesValues, Macroable; |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
16 | |||||||
17 | /** |
||||||
18 | * The source from which to generate items. |
||||||
19 | * |
||||||
20 | * @var callable|static |
||||||
21 | */ |
||||||
22 | public $source; |
||||||
23 | |||||||
24 | /** |
||||||
25 | * Create a new lazy collection instance. |
||||||
26 | * |
||||||
27 | * @param mixed $source |
||||||
28 | * @return void |
||||||
29 | */ |
||||||
30 | public function __construct($source = null) |
||||||
31 | { |
||||||
32 | if ($source instanceof Closure || $source instanceof self) { |
||||||
33 | $this->source = $source; |
||||||
34 | } elseif (is_null($source)) { |
||||||
35 | $this->source = static::empty(); |
||||||
36 | } else { |
||||||
37 | $this->source = $this->getArrayableItems($source); |
||||||
38 | } |
||||||
39 | } |
||||||
40 | |||||||
41 | /** |
||||||
42 | * Create a new instance with no items. |
||||||
43 | * |
||||||
44 | * @return static |
||||||
45 | */ |
||||||
46 | public static function empty() |
||||||
47 | { |
||||||
48 | return new static([]); |
||||||
49 | } |
||||||
50 | |||||||
51 | /** |
||||||
52 | * Create a new instance by invoking the callback a given amount of times. |
||||||
53 | * |
||||||
54 | * @param int $number |
||||||
55 | * @param callable|null $callback |
||||||
56 | * @return static |
||||||
57 | */ |
||||||
58 | public static function times($number, callable $callback = null) |
||||||
59 | { |
||||||
60 | if ($number < 1) { |
||||||
61 | return new static; |
||||||
62 | } |
||||||
63 | |||||||
64 | $instance = new static(function () use ($number) { |
||||||
65 | for ($current = 1; $current <= $number; $current++) { |
||||||
66 | yield $current; |
||||||
67 | } |
||||||
68 | }); |
||||||
69 | |||||||
70 | return is_null($callback) ? $instance : $instance->map($callback); |
||||||
71 | } |
||||||
72 | |||||||
73 | /** |
||||||
74 | * Create an enumerable with the given range. |
||||||
75 | * |
||||||
76 | * @param int $from |
||||||
77 | * @param int $to |
||||||
78 | * @return static |
||||||
79 | */ |
||||||
80 | public static function range($from, $to) |
||||||
81 | { |
||||||
82 | return new static(function () use ($from, $to) { |
||||||
83 | for (; $from <= $to; $from++) { |
||||||
84 | yield $from; |
||||||
85 | } |
||||||
86 | }); |
||||||
87 | } |
||||||
88 | |||||||
89 | /** |
||||||
90 | * Get all items in the enumerable. |
||||||
91 | * |
||||||
92 | * @return array |
||||||
93 | */ |
||||||
94 | public function all() |
||||||
95 | { |
||||||
96 | if (is_array($this->source)) { |
||||||
97 | return $this->source; |
||||||
98 | } |
||||||
99 | |||||||
100 | return iterator_to_array($this->getIterator()); |
||||||
101 | } |
||||||
102 | |||||||
103 | /** |
||||||
104 | * Eager load all items into a new lazy collection backed by an array. |
||||||
105 | * |
||||||
106 | * @return static |
||||||
107 | */ |
||||||
108 | public function eager() |
||||||
109 | { |
||||||
110 | return new static($this->all()); |
||||||
111 | } |
||||||
112 | |||||||
113 | /** |
||||||
114 | * Cache values as they're enumerated. |
||||||
115 | * |
||||||
116 | * @return static |
||||||
117 | */ |
||||||
118 | public function remember() |
||||||
119 | { |
||||||
120 | $iterator = $this->getIterator(); |
||||||
121 | |||||||
122 | $iteratorIndex = 0; |
||||||
123 | |||||||
124 | $cache = []; |
||||||
125 | |||||||
126 | return new static(function () use ($iterator, &$iteratorIndex, &$cache) { |
||||||
127 | for ($index = 0; true; $index++) { |
||||||
128 | if (array_key_exists($index, $cache)) { |
||||||
129 | yield $cache[$index][0] => $cache[$index][1]; |
||||||
130 | |||||||
131 | continue; |
||||||
132 | } |
||||||
133 | |||||||
134 | if ($iteratorIndex < $index) { |
||||||
135 | $iterator->next(); |
||||||
0 ignored issues
–
show
The method
next() does not exist on Traversable . It seems like you code against a sub-type of Traversable such as IntlCodePointBreakIterator or Yaf_Config_Simple or Yaf\Session or IntlRuleBasedBreakIterator or Yaf_Session or Yaf\Config\Simple or Yaf\Config\Ini or Iterator or Yaf_Config_Ini or IntlBreakIterator or MongoGridFSCursor or Doctrine\Common\Collections\Collection or MuCTS\Collections\Collection or MuCTS\Collections\LazyCollection or Symfony\Component\Form\Test\FormInterface or SimpleXMLIterator or Symfony\Component\Form\Test\FormBuilderInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
136 | |||||||
137 | $iteratorIndex++; |
||||||
138 | } |
||||||
139 | |||||||
140 | if (!$iterator->valid()) { |
||||||
0 ignored issues
–
show
The method
valid() does not exist on Traversable . It seems like you code against a sub-type of Traversable such as Yaf_Config_Simple or Yaf\Session or Yaf_Session or Yaf\Config\Simple or Yaf\Config\Ini or Iterator or Yaf_Config_Ini or MongoGridFSCursor or MuCTS\Collections\Collection or MuCTS\Collections\LazyCollection or Symfony\Component\Form\Test\FormInterface or SimpleXMLIterator or Symfony\Component\Form\Test\FormBuilderInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
141 | break; |
||||||
142 | } |
||||||
143 | |||||||
144 | $cache[$index] = [$iterator->key(), $iterator->current()]; |
||||||
0 ignored issues
–
show
The method
current() does not exist on Traversable . It seems like you code against a sub-type of Traversable such as IntlCodePointBreakIterator or Yaf_Config_Simple or Yaf\Session or IntlRuleBasedBreakIterator or Yaf_Session or Yaf\Config\Simple or Yaf\Config\Ini or Iterator or Yaf_Config_Ini or IntlBreakIterator or MongoGridFSCursor or Doctrine\Common\Collections\Collection or MuCTS\Collections\Collection or MuCTS\Collections\LazyCollection or Symfony\Component\Form\Test\FormInterface or SimpleXMLIterator or Symfony\Component\Form\Test\FormBuilderInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() The method
key() does not exist on Traversable . It seems like you code against a sub-type of Traversable such as Yaf_Config_Simple or Yaf\Session or Yaf_Session or Yaf\Config\Simple or Yaf\Config\Ini or Iterator or Yaf_Config_Ini or MongoGridFSCursor or Doctrine\Common\Collections\Collection or MuCTS\Collections\Collection or MuCTS\Collections\LazyCollection or Symfony\Component\Form\Test\FormInterface or SimpleXMLIterator or Symfony\Component\Form\Test\FormBuilderInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
145 | |||||||
146 | yield $cache[$index][0] => $cache[$index][1]; |
||||||
147 | } |
||||||
148 | }); |
||||||
149 | } |
||||||
150 | |||||||
151 | /** |
||||||
152 | * Get the average value of a given key. |
||||||
153 | * |
||||||
154 | * @param callable|string|null $callback |
||||||
155 | * @return mixed |
||||||
156 | */ |
||||||
157 | public function avg($callback = null) |
||||||
158 | { |
||||||
159 | return $this->collect()->avg($callback); |
||||||
160 | } |
||||||
161 | |||||||
162 | /** |
||||||
163 | * Get the median of a given key. |
||||||
164 | * |
||||||
165 | * @param string|array|null $key |
||||||
166 | * @return mixed |
||||||
167 | */ |
||||||
168 | public function median($key = null) |
||||||
169 | { |
||||||
170 | return $this->collect()->median($key); |
||||||
171 | } |
||||||
172 | |||||||
173 | /** |
||||||
174 | * Get the mode of a given key. |
||||||
175 | * |
||||||
176 | * @param string|array|null $key |
||||||
177 | * @return array|null |
||||||
178 | */ |
||||||
179 | public function mode($key = null) |
||||||
180 | { |
||||||
181 | return $this->collect()->mode($key); |
||||||
182 | } |
||||||
183 | |||||||
184 | /** |
||||||
185 | * Collapse the collection of items into a single array. |
||||||
186 | * |
||||||
187 | * @return static |
||||||
188 | */ |
||||||
189 | public function collapse() |
||||||
190 | { |
||||||
191 | return new static(function () { |
||||||
192 | foreach ($this as $values) { |
||||||
193 | if (is_array($values) || $values instanceof Enumerable) { |
||||||
194 | foreach ($values as $value) { |
||||||
195 | yield $value; |
||||||
196 | } |
||||||
197 | } |
||||||
198 | } |
||||||
199 | }); |
||||||
200 | } |
||||||
201 | |||||||
202 | /** |
||||||
203 | * Determine if an item exists in the enumerable. |
||||||
204 | * |
||||||
205 | * @param mixed $key |
||||||
206 | * @param mixed $operator |
||||||
207 | * @param mixed $value |
||||||
208 | * @return bool |
||||||
209 | */ |
||||||
210 | public function contains($key, $operator = null, $value = null) |
||||||
211 | { |
||||||
212 | if (func_num_args() === 1 && $this->useAsCallable($key)) { |
||||||
213 | $placeholder = new stdClass; |
||||||
214 | |||||||
215 | return $this->first($key, $placeholder) !== $placeholder; |
||||||
216 | } |
||||||
217 | |||||||
218 | if (func_num_args() === 1) { |
||||||
219 | $needle = $key; |
||||||
220 | |||||||
221 | foreach ($this as $value) { |
||||||
222 | if ($value == $needle) { |
||||||
223 | return true; |
||||||
224 | } |
||||||
225 | } |
||||||
226 | |||||||
227 | return false; |
||||||
228 | } |
||||||
229 | |||||||
230 | return $this->contains($this->operatorForWhere(...func_get_args())); |
||||||
0 ignored issues
–
show
func_get_args() is expanded, but the parameter $key of MuCTS\Collections\LazyCo...ion::operatorForWhere() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
231 | } |
||||||
232 | |||||||
233 | /** |
||||||
234 | * Cross join the given iterables, returning all possible permutations. |
||||||
235 | * |
||||||
236 | * @param array ...$arrays |
||||||
237 | * @return static |
||||||
238 | */ |
||||||
239 | public function crossJoin(...$arrays) |
||||||
240 | { |
||||||
241 | return $this->passthru('crossJoin', func_get_args()); |
||||||
242 | } |
||||||
243 | |||||||
244 | /** |
||||||
245 | * Count the number of items in the collection by a field or using a callback. |
||||||
246 | * |
||||||
247 | * @param callable|string $countBy |
||||||
248 | * @return static |
||||||
249 | */ |
||||||
250 | public function countBy($countBy = null) |
||||||
251 | { |
||||||
252 | $countBy = is_null($countBy) |
||||||
253 | ? $this->identity() |
||||||
254 | : $this->valueRetriever($countBy); |
||||||
255 | |||||||
256 | return new static(function () use ($countBy) { |
||||||
257 | $counts = []; |
||||||
258 | |||||||
259 | foreach ($this as $key => $value) { |
||||||
260 | $group = $countBy($value, $key); |
||||||
261 | |||||||
262 | if (empty($counts[$group])) { |
||||||
263 | $counts[$group] = 0; |
||||||
264 | } |
||||||
265 | |||||||
266 | $counts[$group]++; |
||||||
267 | } |
||||||
268 | |||||||
269 | yield from $counts; |
||||||
270 | }); |
||||||
271 | } |
||||||
272 | |||||||
273 | /** |
||||||
274 | * Get the items that are not present in the given items. |
||||||
275 | * |
||||||
276 | * @param mixed $items |
||||||
277 | * @return static |
||||||
278 | */ |
||||||
279 | public function diff($items) |
||||||
280 | { |
||||||
281 | return $this->passthru('diff', func_get_args()); |
||||||
282 | } |
||||||
283 | |||||||
284 | /** |
||||||
285 | * Get the items that are not present in the given items, using the callback. |
||||||
286 | * |
||||||
287 | * @param mixed $items |
||||||
288 | * @param callable $callback |
||||||
289 | * @return static |
||||||
290 | */ |
||||||
291 | public function diffUsing($items, callable $callback) |
||||||
292 | { |
||||||
293 | return $this->passthru('diffUsing', func_get_args()); |
||||||
294 | } |
||||||
295 | |||||||
296 | /** |
||||||
297 | * Get the items whose keys and values are not present in the given items. |
||||||
298 | * |
||||||
299 | * @param mixed $items |
||||||
300 | * @return static |
||||||
301 | */ |
||||||
302 | public function diffAssoc($items) |
||||||
303 | { |
||||||
304 | return $this->passthru('diffAssoc', func_get_args()); |
||||||
305 | } |
||||||
306 | |||||||
307 | /** |
||||||
308 | * Get the items whose keys and values are not present in the given items, using the callback. |
||||||
309 | * |
||||||
310 | * @param mixed $items |
||||||
311 | * @param callable $callback |
||||||
312 | * @return static |
||||||
313 | */ |
||||||
314 | public function diffAssocUsing($items, callable $callback) |
||||||
315 | { |
||||||
316 | return $this->passthru('diffAssocUsing', func_get_args()); |
||||||
317 | } |
||||||
318 | |||||||
319 | /** |
||||||
320 | * Get the items whose keys are not present in the given items. |
||||||
321 | * |
||||||
322 | * @param mixed $items |
||||||
323 | * @return static |
||||||
324 | */ |
||||||
325 | public function diffKeys($items) |
||||||
326 | { |
||||||
327 | return $this->passthru('diffKeys', func_get_args()); |
||||||
328 | } |
||||||
329 | |||||||
330 | /** |
||||||
331 | * Get the items whose keys are not present in the given items, using the callback. |
||||||
332 | * |
||||||
333 | * @param mixed $items |
||||||
334 | * @param callable $callback |
||||||
335 | * @return static |
||||||
336 | */ |
||||||
337 | public function diffKeysUsing($items, callable $callback) |
||||||
338 | { |
||||||
339 | return $this->passthru('diffKeysUsing', func_get_args()); |
||||||
340 | } |
||||||
341 | |||||||
342 | /** |
||||||
343 | * Retrieve duplicate items. |
||||||
344 | * |
||||||
345 | * @param callable|null $callback |
||||||
346 | * @param bool $strict |
||||||
347 | * @return static |
||||||
348 | */ |
||||||
349 | public function duplicates($callback = null, $strict = false) |
||||||
350 | { |
||||||
351 | return $this->passthru('duplicates', func_get_args()); |
||||||
352 | } |
||||||
353 | |||||||
354 | /** |
||||||
355 | * Retrieve duplicate items using strict comparison. |
||||||
356 | * |
||||||
357 | * @param callable|null $callback |
||||||
358 | * @return static |
||||||
359 | */ |
||||||
360 | public function duplicatesStrict($callback = null) |
||||||
361 | { |
||||||
362 | return $this->passthru('duplicatesStrict', func_get_args()); |
||||||
363 | } |
||||||
364 | |||||||
365 | /** |
||||||
366 | * Get all items except for those with the specified keys. |
||||||
367 | * |
||||||
368 | * @param mixed $keys |
||||||
369 | * @return static |
||||||
370 | */ |
||||||
371 | public function except($keys) |
||||||
372 | { |
||||||
373 | return $this->passthru('except', func_get_args()); |
||||||
374 | } |
||||||
375 | |||||||
376 | /** |
||||||
377 | * Run a filter over each of the items. |
||||||
378 | * |
||||||
379 | * @param callable|null $callback |
||||||
380 | * @return static |
||||||
381 | */ |
||||||
382 | public function filter(callable $callback = null) |
||||||
383 | { |
||||||
384 | if (is_null($callback)) { |
||||||
385 | $callback = function ($value) { |
||||||
386 | return (bool)$value; |
||||||
387 | }; |
||||||
388 | } |
||||||
389 | |||||||
390 | return new static(function () use ($callback) { |
||||||
391 | foreach ($this as $key => $value) { |
||||||
392 | if ($callback($value, $key)) { |
||||||
393 | yield $key => $value; |
||||||
394 | } |
||||||
395 | } |
||||||
396 | }); |
||||||
397 | } |
||||||
398 | |||||||
399 | /** |
||||||
400 | * Get the first item from the enumerable passing the given truth test. |
||||||
401 | * |
||||||
402 | * @param callable|null $callback |
||||||
403 | * @param mixed $default |
||||||
404 | * @return mixed |
||||||
405 | */ |
||||||
406 | public function first(callable $callback = null, $default = null) |
||||||
407 | { |
||||||
408 | $iterator = $this->getIterator(); |
||||||
409 | |||||||
410 | if (is_null($callback)) { |
||||||
411 | if (!$iterator->valid()) { |
||||||
412 | return value($default); |
||||||
413 | } |
||||||
414 | |||||||
415 | return $iterator->current(); |
||||||
416 | } |
||||||
417 | |||||||
418 | foreach ($iterator as $key => $value) { |
||||||
419 | if ($callback($value, $key)) { |
||||||
420 | return $value; |
||||||
421 | } |
||||||
422 | } |
||||||
423 | |||||||
424 | return value($default); |
||||||
425 | } |
||||||
426 | |||||||
427 | /** |
||||||
428 | * Get a flattened list of the items in the collection. |
||||||
429 | * |
||||||
430 | * @param int $depth |
||||||
431 | * @return static |
||||||
432 | */ |
||||||
433 | public function flatten($depth = INF) |
||||||
434 | { |
||||||
435 | $instance = new static(function () use ($depth) { |
||||||
436 | foreach ($this as $item) { |
||||||
437 | if (!is_array($item) && !$item instanceof Enumerable) { |
||||||
438 | yield $item; |
||||||
439 | } elseif ($depth === 1) { |
||||||
440 | yield from $item; |
||||||
441 | } else { |
||||||
442 | yield from (new static($item))->flatten($depth - 1); |
||||||
0 ignored issues
–
show
$depth - 1 of type double is incompatible with the type integer expected by parameter $depth of MuCTS\Collections\LazyCollection::flatten() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
443 | } |
||||||
444 | } |
||||||
445 | }); |
||||||
446 | |||||||
447 | return $instance->values(); |
||||||
448 | } |
||||||
449 | |||||||
450 | /** |
||||||
451 | * Flip the items in the collection. |
||||||
452 | * |
||||||
453 | * @return static |
||||||
454 | */ |
||||||
455 | public function flip() |
||||||
456 | { |
||||||
457 | return new static(function () { |
||||||
458 | foreach ($this as $key => $value) { |
||||||
459 | yield $value => $key; |
||||||
460 | } |
||||||
461 | }); |
||||||
462 | } |
||||||
463 | |||||||
464 | /** |
||||||
465 | * Get an item by key. |
||||||
466 | * |
||||||
467 | * @param mixed $key |
||||||
468 | * @param mixed $default |
||||||
469 | * @return mixed |
||||||
470 | */ |
||||||
471 | public function get($key, $default = null) |
||||||
472 | { |
||||||
473 | if (is_null($key)) { |
||||||
474 | return null; |
||||||
475 | } |
||||||
476 | |||||||
477 | foreach ($this as $outerKey => $outerValue) { |
||||||
478 | if ($outerKey == $key) { |
||||||
479 | return $outerValue; |
||||||
480 | } |
||||||
481 | } |
||||||
482 | |||||||
483 | return value($default); |
||||||
484 | } |
||||||
485 | |||||||
486 | /** |
||||||
487 | * Group an associative array by a field or using a callback. |
||||||
488 | * |
||||||
489 | * @param array|callable|string $groupBy |
||||||
490 | * @param bool $preserveKeys |
||||||
491 | * @return static |
||||||
492 | */ |
||||||
493 | public function groupBy($groupBy, $preserveKeys = false) |
||||||
494 | { |
||||||
495 | return $this->passthru('groupBy', func_get_args()); |
||||||
496 | } |
||||||
497 | |||||||
498 | /** |
||||||
499 | * Key an associative array by a field or using a callback. |
||||||
500 | * |
||||||
501 | * @param callable|string $keyBy |
||||||
502 | * @return static |
||||||
503 | */ |
||||||
504 | public function keyBy($keyBy) |
||||||
505 | { |
||||||
506 | return new static(function () use ($keyBy) { |
||||||
507 | $keyBy = $this->valueRetriever($keyBy); |
||||||
508 | |||||||
509 | foreach ($this as $key => $item) { |
||||||
510 | $resolvedKey = $keyBy($item, $key); |
||||||
511 | |||||||
512 | if (is_object($resolvedKey)) { |
||||||
513 | $resolvedKey = (string)$resolvedKey; |
||||||
514 | } |
||||||
515 | |||||||
516 | yield $resolvedKey => $item; |
||||||
517 | } |
||||||
518 | }); |
||||||
519 | } |
||||||
520 | |||||||
521 | /** |
||||||
522 | * Determine if an item exists in the collection by key. |
||||||
523 | * |
||||||
524 | * @param mixed $key |
||||||
525 | * @return bool |
||||||
526 | */ |
||||||
527 | public function has($key) |
||||||
528 | { |
||||||
529 | $keys = array_flip(is_array($key) ? $key : func_get_args()); |
||||||
530 | $count = count($keys); |
||||||
531 | |||||||
532 | foreach ($this as $key => $value) { |
||||||
0 ignored issues
–
show
|
|||||||
533 | if (array_key_exists($key, $keys) && --$count == 0) { |
||||||
534 | return true; |
||||||
535 | } |
||||||
536 | } |
||||||
537 | |||||||
538 | return false; |
||||||
539 | } |
||||||
540 | |||||||
541 | /** |
||||||
542 | * Concatenate values of a given key as a string. |
||||||
543 | * |
||||||
544 | * @param string $value |
||||||
545 | * @param string|null $glue |
||||||
546 | * @return string |
||||||
547 | */ |
||||||
548 | public function implode($value, $glue = null) |
||||||
549 | { |
||||||
550 | return $this->collect()->implode(...func_get_args()); |
||||||
0 ignored issues
–
show
func_get_args() is expanded, but the parameter $value of MuCTS\Collections\Collection::implode() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
551 | } |
||||||
552 | |||||||
553 | /** |
||||||
554 | * Intersect the collection with the given items. |
||||||
555 | * |
||||||
556 | * @param mixed $items |
||||||
557 | * @return static |
||||||
558 | */ |
||||||
559 | public function intersect($items) |
||||||
560 | { |
||||||
561 | return $this->passthru('intersect', func_get_args()); |
||||||
562 | } |
||||||
563 | |||||||
564 | /** |
||||||
565 | * Intersect the collection with the given items by key. |
||||||
566 | * |
||||||
567 | * @param mixed $items |
||||||
568 | * @return static |
||||||
569 | */ |
||||||
570 | public function intersectByKeys($items) |
||||||
571 | { |
||||||
572 | return $this->passthru('intersectByKeys', func_get_args()); |
||||||
573 | } |
||||||
574 | |||||||
575 | /** |
||||||
576 | * Determine if the items is empty or not. |
||||||
577 | * |
||||||
578 | * @return bool |
||||||
579 | */ |
||||||
580 | public function isEmpty() |
||||||
581 | { |
||||||
582 | return !$this->getIterator()->valid(); |
||||||
583 | } |
||||||
584 | |||||||
585 | /** |
||||||
586 | * Join all items from the collection using a string. The final items can use a separate glue string. |
||||||
587 | * |
||||||
588 | * @param string $glue |
||||||
589 | * @param string $finalGlue |
||||||
590 | * @return string |
||||||
591 | */ |
||||||
592 | public function join($glue, $finalGlue = '') |
||||||
593 | { |
||||||
594 | return $this->collect()->join(...func_get_args()); |
||||||
0 ignored issues
–
show
func_get_args() is expanded, but the parameter $glue of MuCTS\Collections\Collection::join() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
595 | } |
||||||
596 | |||||||
597 | /** |
||||||
598 | * Get the keys of the collection items. |
||||||
599 | * |
||||||
600 | * @return static |
||||||
601 | */ |
||||||
602 | public function keys() |
||||||
603 | { |
||||||
604 | return new static(function () { |
||||||
605 | foreach ($this as $key => $value) { |
||||||
606 | yield $key; |
||||||
607 | } |
||||||
608 | }); |
||||||
609 | } |
||||||
610 | |||||||
611 | /** |
||||||
612 | * Get the last item from the collection. |
||||||
613 | * |
||||||
614 | * @param callable|null $callback |
||||||
615 | * @param mixed $default |
||||||
616 | * @return mixed |
||||||
617 | */ |
||||||
618 | public function last(callable $callback = null, $default = null) |
||||||
619 | { |
||||||
620 | $needle = $placeholder = new stdClass; |
||||||
621 | |||||||
622 | foreach ($this as $key => $value) { |
||||||
623 | if (is_null($callback) || $callback($value, $key)) { |
||||||
624 | $needle = $value; |
||||||
625 | } |
||||||
626 | } |
||||||
627 | |||||||
628 | return $needle === $placeholder ? value($default) : $needle; |
||||||
629 | } |
||||||
630 | |||||||
631 | /** |
||||||
632 | * Get the values of a given key. |
||||||
633 | * |
||||||
634 | * @param string|array $value |
||||||
635 | * @param string|null $key |
||||||
636 | * @return static |
||||||
637 | */ |
||||||
638 | public function pluck($value, $key = null) |
||||||
639 | { |
||||||
640 | return new static(function () use ($value, $key) { |
||||||
641 | [$value, $key] = $this->explodePluckParameters($value, $key); |
||||||
642 | |||||||
643 | foreach ($this as $item) { |
||||||
644 | $itemValue = data_get($item, $value); |
||||||
645 | |||||||
646 | if (is_null($key)) { |
||||||
647 | yield $itemValue; |
||||||
648 | } else { |
||||||
649 | $itemKey = data_get($item, $key); |
||||||
650 | |||||||
651 | if (is_object($itemKey) && method_exists($itemKey, '__toString')) { |
||||||
652 | $itemKey = (string)$itemKey; |
||||||
653 | } |
||||||
654 | |||||||
655 | yield $itemKey => $itemValue; |
||||||
656 | } |
||||||
657 | } |
||||||
658 | }); |
||||||
659 | } |
||||||
660 | |||||||
661 | /** |
||||||
662 | * Run a map over each of the items. |
||||||
663 | * |
||||||
664 | * @param callable $callback |
||||||
665 | * @return static |
||||||
666 | */ |
||||||
667 | public function map(callable $callback) |
||||||
668 | { |
||||||
669 | return new static(function () use ($callback) { |
||||||
670 | foreach ($this as $key => $value) { |
||||||
671 | yield $key => $callback($value, $key); |
||||||
672 | } |
||||||
673 | }); |
||||||
674 | } |
||||||
675 | |||||||
676 | /** |
||||||
677 | * Run a dictionary map over the items. |
||||||
678 | * |
||||||
679 | * The callback should return an associative array with a single key/value pair. |
||||||
680 | * |
||||||
681 | * @param callable $callback |
||||||
682 | * @return static |
||||||
683 | */ |
||||||
684 | public function mapToDictionary(callable $callback) |
||||||
685 | { |
||||||
686 | return $this->passthru('mapToDictionary', func_get_args()); |
||||||
687 | } |
||||||
688 | |||||||
689 | /** |
||||||
690 | * Run an associative map over each of the items. |
||||||
691 | * |
||||||
692 | * The callback should return an associative array with a single key/value pair. |
||||||
693 | * |
||||||
694 | * @param callable $callback |
||||||
695 | * @return static |
||||||
696 | */ |
||||||
697 | public function mapWithKeys(callable $callback) |
||||||
698 | { |
||||||
699 | return new static(function () use ($callback) { |
||||||
700 | foreach ($this as $key => $value) { |
||||||
701 | yield from $callback($value, $key); |
||||||
702 | } |
||||||
703 | }); |
||||||
704 | } |
||||||
705 | |||||||
706 | /** |
||||||
707 | * Merge the collection with the given items. |
||||||
708 | * |
||||||
709 | * @param mixed $items |
||||||
710 | * @return static |
||||||
711 | */ |
||||||
712 | public function merge($items) |
||||||
713 | { |
||||||
714 | return $this->passthru('merge', func_get_args()); |
||||||
715 | } |
||||||
716 | |||||||
717 | /** |
||||||
718 | * Recursively merge the collection with the given items. |
||||||
719 | * |
||||||
720 | * @param mixed $items |
||||||
721 | * @return static |
||||||
722 | */ |
||||||
723 | public function mergeRecursive($items) |
||||||
724 | { |
||||||
725 | return $this->passthru('mergeRecursive', func_get_args()); |
||||||
726 | } |
||||||
727 | |||||||
728 | /** |
||||||
729 | * Create a collection by using this collection for keys and another for its values. |
||||||
730 | * |
||||||
731 | * @param mixed $values |
||||||
732 | * @return static |
||||||
733 | */ |
||||||
734 | public function combine($values) |
||||||
735 | { |
||||||
736 | return new static(function () use ($values) { |
||||||
737 | $values = $this->makeIterator($values); |
||||||
738 | |||||||
739 | $errorMessage = 'Both parameters should have an equal number of elements'; |
||||||
740 | |||||||
741 | foreach ($this as $key) { |
||||||
742 | if (!$values->valid()) { |
||||||
743 | trigger_error($errorMessage, E_USER_WARNING); |
||||||
744 | |||||||
745 | break; |
||||||
746 | } |
||||||
747 | |||||||
748 | yield $key => $values->current(); |
||||||
749 | |||||||
750 | $values->next(); |
||||||
751 | } |
||||||
752 | |||||||
753 | if ($values->valid()) { |
||||||
754 | trigger_error($errorMessage, E_USER_WARNING); |
||||||
755 | } |
||||||
756 | }); |
||||||
757 | } |
||||||
758 | |||||||
759 | /** |
||||||
760 | * Union the collection with the given items. |
||||||
761 | * |
||||||
762 | * @param mixed $items |
||||||
763 | * @return static |
||||||
764 | */ |
||||||
765 | public function union($items) |
||||||
766 | { |
||||||
767 | return $this->passthru('union', func_get_args()); |
||||||
768 | } |
||||||
769 | |||||||
770 | /** |
||||||
771 | * Create a new collection consisting of every n-th element. |
||||||
772 | * |
||||||
773 | * @param int $step |
||||||
774 | * @param int $offset |
||||||
775 | * @return static |
||||||
776 | */ |
||||||
777 | public function nth($step, $offset = 0) |
||||||
778 | { |
||||||
779 | return new static(function () use ($step, $offset) { |
||||||
780 | $position = 0; |
||||||
781 | |||||||
782 | foreach ($this as $item) { |
||||||
783 | if ($position % $step === $offset) { |
||||||
784 | yield $item; |
||||||
785 | } |
||||||
786 | |||||||
787 | $position++; |
||||||
788 | } |
||||||
789 | }); |
||||||
790 | } |
||||||
791 | |||||||
792 | /** |
||||||
793 | * Get the items with the specified keys. |
||||||
794 | * |
||||||
795 | * @param mixed $keys |
||||||
796 | * @return static |
||||||
797 | */ |
||||||
798 | public function only($keys) |
||||||
799 | { |
||||||
800 | if ($keys instanceof Enumerable) { |
||||||
801 | $keys = $keys->all(); |
||||||
802 | } elseif (!is_null($keys)) { |
||||||
803 | $keys = is_array($keys) ? $keys : func_get_args(); |
||||||
804 | } |
||||||
805 | |||||||
806 | return new static(function () use ($keys) { |
||||||
807 | if (is_null($keys)) { |
||||||
808 | yield from $this; |
||||||
809 | } else { |
||||||
810 | $keys = array_flip($keys); |
||||||
811 | |||||||
812 | foreach ($this as $key => $value) { |
||||||
813 | if (array_key_exists($key, $keys)) { |
||||||
814 | yield $key => $value; |
||||||
815 | |||||||
816 | unset($keys[$key]); |
||||||
817 | |||||||
818 | if (empty($keys)) { |
||||||
819 | break; |
||||||
820 | } |
||||||
821 | } |
||||||
822 | } |
||||||
823 | } |
||||||
824 | }); |
||||||
825 | } |
||||||
826 | |||||||
827 | /** |
||||||
828 | * Push all of the given items onto the collection. |
||||||
829 | * |
||||||
830 | * @param iterable $source |
||||||
831 | * @return static |
||||||
832 | */ |
||||||
833 | public function concat($source) |
||||||
834 | { |
||||||
835 | return (new static(function () use ($source) { |
||||||
836 | yield from $this; |
||||||
837 | yield from $source; |
||||||
838 | }))->values(); |
||||||
839 | } |
||||||
840 | |||||||
841 | /** |
||||||
842 | * Get one or a specified number of items randomly from the collection. |
||||||
843 | * |
||||||
844 | * @param int|null $number |
||||||
845 | * @return static|mixed |
||||||
846 | * |
||||||
847 | * @throws \InvalidArgumentException |
||||||
848 | */ |
||||||
849 | public function random($number = null) |
||||||
850 | { |
||||||
851 | $result = $this->collect()->random(...func_get_args()); |
||||||
0 ignored issues
–
show
func_get_args() is expanded, but the parameter $number of MuCTS\Collections\Collection::random() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
852 | |||||||
853 | return is_null($number) ? $result : new static($result); |
||||||
854 | } |
||||||
855 | |||||||
856 | /** |
||||||
857 | * Reduce the collection to a single value. |
||||||
858 | * |
||||||
859 | * @param callable $callback |
||||||
860 | * @param mixed $initial |
||||||
861 | * @return mixed |
||||||
862 | */ |
||||||
863 | public function reduce(callable $callback, $initial = null) |
||||||
864 | { |
||||||
865 | $result = $initial; |
||||||
866 | |||||||
867 | foreach ($this as $value) { |
||||||
868 | $result = $callback($result, $value); |
||||||
869 | } |
||||||
870 | |||||||
871 | return $result; |
||||||
872 | } |
||||||
873 | |||||||
874 | /** |
||||||
875 | * Replace the collection items with the given items. |
||||||
876 | * |
||||||
877 | * @param mixed $items |
||||||
878 | * @return static |
||||||
879 | */ |
||||||
880 | public function replace($items) |
||||||
881 | { |
||||||
882 | return new static(function () use ($items) { |
||||||
883 | $items = $this->getArrayableItems($items); |
||||||
884 | |||||||
885 | foreach ($this as $key => $value) { |
||||||
886 | if (array_key_exists($key, $items)) { |
||||||
887 | yield $key => $items[$key]; |
||||||
888 | |||||||
889 | unset($items[$key]); |
||||||
890 | } else { |
||||||
891 | yield $key => $value; |
||||||
892 | } |
||||||
893 | } |
||||||
894 | |||||||
895 | foreach ($items as $key => $value) { |
||||||
896 | yield $key => $value; |
||||||
897 | } |
||||||
898 | }); |
||||||
899 | } |
||||||
900 | |||||||
901 | /** |
||||||
902 | * Recursively replace the collection items with the given items. |
||||||
903 | * |
||||||
904 | * @param mixed $items |
||||||
905 | * @return static |
||||||
906 | */ |
||||||
907 | public function replaceRecursive($items) |
||||||
908 | { |
||||||
909 | return $this->passthru('replaceRecursive', func_get_args()); |
||||||
910 | } |
||||||
911 | |||||||
912 | /** |
||||||
913 | * Reverse items order. |
||||||
914 | * |
||||||
915 | * @return static |
||||||
916 | */ |
||||||
917 | public function reverse() |
||||||
918 | { |
||||||
919 | return $this->passthru('reverse', func_get_args()); |
||||||
920 | } |
||||||
921 | |||||||
922 | /** |
||||||
923 | * Search the collection for a given value and return the corresponding key if successful. |
||||||
924 | * |
||||||
925 | * @param mixed $value |
||||||
926 | * @param bool $strict |
||||||
927 | * @return mixed |
||||||
928 | */ |
||||||
929 | public function search($value, $strict = false) |
||||||
930 | { |
||||||
931 | $predicate = $this->useAsCallable($value) |
||||||
932 | ? $value |
||||||
933 | : function ($item) use ($value, $strict) { |
||||||
934 | return $strict ? $item === $value : $item == $value; |
||||||
935 | }; |
||||||
936 | |||||||
937 | foreach ($this as $key => $item) { |
||||||
938 | if ($predicate($item, $key)) { |
||||||
939 | return $key; |
||||||
940 | } |
||||||
941 | } |
||||||
942 | |||||||
943 | return false; |
||||||
944 | } |
||||||
945 | |||||||
946 | /** |
||||||
947 | * Shuffle the items in the collection. |
||||||
948 | * |
||||||
949 | * @param int|null $seed |
||||||
950 | * @return static |
||||||
951 | */ |
||||||
952 | public function shuffle($seed = null) |
||||||
953 | { |
||||||
954 | return $this->passthru('shuffle', func_get_args()); |
||||||
955 | } |
||||||
956 | |||||||
957 | /** |
||||||
958 | * Skip the first {$count} items. |
||||||
959 | * |
||||||
960 | * @param int $count |
||||||
961 | * @return static |
||||||
962 | */ |
||||||
963 | public function skip($count) |
||||||
964 | { |
||||||
965 | return new static(function () use ($count) { |
||||||
966 | $iterator = $this->getIterator(); |
||||||
967 | |||||||
968 | while ($iterator->valid() && $count--) { |
||||||
969 | $iterator->next(); |
||||||
970 | } |
||||||
971 | |||||||
972 | while ($iterator->valid()) { |
||||||
973 | yield $iterator->key() => $iterator->current(); |
||||||
974 | |||||||
975 | $iterator->next(); |
||||||
976 | } |
||||||
977 | }); |
||||||
978 | } |
||||||
979 | |||||||
980 | /** |
||||||
981 | * Skip items in the collection until the given condition is met. |
||||||
982 | * |
||||||
983 | * @param mixed $value |
||||||
984 | * @return static |
||||||
985 | */ |
||||||
986 | public function skipUntil($value) |
||||||
987 | { |
||||||
988 | $callback = $this->useAsCallable($value) ? $value : $this->equality($value); |
||||||
989 | |||||||
990 | return $this->skipWhile($this->negate($callback)); |
||||||
991 | } |
||||||
992 | |||||||
993 | /** |
||||||
994 | * Skip items in the collection while the given condition is met. |
||||||
995 | * |
||||||
996 | * @param mixed $value |
||||||
997 | * @return static |
||||||
998 | */ |
||||||
999 | public function skipWhile($value) |
||||||
1000 | { |
||||||
1001 | $callback = $this->useAsCallable($value) ? $value : $this->equality($value); |
||||||
1002 | |||||||
1003 | return new static(function () use ($callback) { |
||||||
1004 | $iterator = $this->getIterator(); |
||||||
1005 | |||||||
1006 | while ($iterator->valid() && $callback($iterator->current(), $iterator->key())) { |
||||||
1007 | $iterator->next(); |
||||||
1008 | } |
||||||
1009 | |||||||
1010 | while ($iterator->valid()) { |
||||||
1011 | yield $iterator->key() => $iterator->current(); |
||||||
1012 | |||||||
1013 | $iterator->next(); |
||||||
1014 | } |
||||||
1015 | }); |
||||||
1016 | } |
||||||
1017 | |||||||
1018 | /** |
||||||
1019 | * Get a slice of items from the enumerable. |
||||||
1020 | * |
||||||
1021 | * @param int $offset |
||||||
1022 | * @param int|null $length |
||||||
1023 | * @return static |
||||||
1024 | */ |
||||||
1025 | public function slice($offset, $length = null) |
||||||
1026 | { |
||||||
1027 | if ($offset < 0 || $length < 0) { |
||||||
1028 | return $this->passthru('slice', func_get_args()); |
||||||
1029 | } |
||||||
1030 | |||||||
1031 | $instance = $this->skip($offset); |
||||||
1032 | |||||||
1033 | return is_null($length) ? $instance : $instance->take($length); |
||||||
1034 | } |
||||||
1035 | |||||||
1036 | /** |
||||||
1037 | * Split a collection into a certain number of groups. |
||||||
1038 | * |
||||||
1039 | * @param int $numberOfGroups |
||||||
1040 | * @return static |
||||||
1041 | */ |
||||||
1042 | public function split($numberOfGroups) |
||||||
1043 | { |
||||||
1044 | return $this->passthru('split', func_get_args()); |
||||||
1045 | } |
||||||
1046 | |||||||
1047 | /** |
||||||
1048 | * Chunk the collection into chunks of the given size. |
||||||
1049 | * |
||||||
1050 | * @param int $size |
||||||
1051 | * @return static |
||||||
1052 | */ |
||||||
1053 | public function chunk($size) |
||||||
1054 | { |
||||||
1055 | if ($size <= 0) { |
||||||
1056 | return static::empty(); |
||||||
1057 | } |
||||||
1058 | |||||||
1059 | return new static(function () use ($size) { |
||||||
1060 | $iterator = $this->getIterator(); |
||||||
1061 | |||||||
1062 | while ($iterator->valid()) { |
||||||
1063 | $chunk = []; |
||||||
1064 | |||||||
1065 | while (true) { |
||||||
1066 | $chunk[$iterator->key()] = $iterator->current(); |
||||||
1067 | |||||||
1068 | if (count($chunk) < $size) { |
||||||
1069 | $iterator->next(); |
||||||
1070 | |||||||
1071 | if (!$iterator->valid()) { |
||||||
1072 | break; |
||||||
1073 | } |
||||||
1074 | } else { |
||||||
1075 | break; |
||||||
1076 | } |
||||||
1077 | } |
||||||
1078 | |||||||
1079 | yield new static($chunk); |
||||||
1080 | |||||||
1081 | $iterator->next(); |
||||||
1082 | } |
||||||
1083 | }); |
||||||
1084 | } |
||||||
1085 | |||||||
1086 | /** |
||||||
1087 | * Sort through each item with a callback. |
||||||
1088 | * |
||||||
1089 | * @param callable|null|int $callback |
||||||
1090 | * @return static |
||||||
1091 | */ |
||||||
1092 | public function sort($callback = null) |
||||||
1093 | { |
||||||
1094 | return $this->passthru('sort', func_get_args()); |
||||||
1095 | } |
||||||
1096 | |||||||
1097 | /** |
||||||
1098 | * Sort items in descending order. |
||||||
1099 | * |
||||||
1100 | * @param int $options |
||||||
1101 | * @return static |
||||||
1102 | */ |
||||||
1103 | public function sortDesc($options = SORT_REGULAR) |
||||||
1104 | { |
||||||
1105 | return $this->passthru('sortDesc', func_get_args()); |
||||||
1106 | } |
||||||
1107 | |||||||
1108 | /** |
||||||
1109 | * Sort the collection using the given callback. |
||||||
1110 | * |
||||||
1111 | * @param callable|string $callback |
||||||
1112 | * @param int $options |
||||||
1113 | * @param bool $descending |
||||||
1114 | * @return static |
||||||
1115 | */ |
||||||
1116 | public function sortBy($callback, $options = SORT_REGULAR, $descending = false) |
||||||
1117 | { |
||||||
1118 | return $this->passthru('sortBy', func_get_args()); |
||||||
1119 | } |
||||||
1120 | |||||||
1121 | /** |
||||||
1122 | * Sort the collection in descending order using the given callback. |
||||||
1123 | * |
||||||
1124 | * @param callable|string $callback |
||||||
1125 | * @param int $options |
||||||
1126 | * @return static |
||||||
1127 | */ |
||||||
1128 | public function sortByDesc($callback, $options = SORT_REGULAR) |
||||||
1129 | { |
||||||
1130 | return $this->passthru('sortByDesc', func_get_args()); |
||||||
1131 | } |
||||||
1132 | |||||||
1133 | /** |
||||||
1134 | * Sort the collection keys. |
||||||
1135 | * |
||||||
1136 | * @param int $options |
||||||
1137 | * @param bool $descending |
||||||
1138 | * @return static |
||||||
1139 | */ |
||||||
1140 | public function sortKeys($options = SORT_REGULAR, $descending = false) |
||||||
1141 | { |
||||||
1142 | return $this->passthru('sortKeys', func_get_args()); |
||||||
1143 | } |
||||||
1144 | |||||||
1145 | /** |
||||||
1146 | * Sort the collection keys in descending order. |
||||||
1147 | * |
||||||
1148 | * @param int $options |
||||||
1149 | * @return static |
||||||
1150 | */ |
||||||
1151 | public function sortKeysDesc($options = SORT_REGULAR) |
||||||
1152 | { |
||||||
1153 | return $this->passthru('sortKeysDesc', func_get_args()); |
||||||
1154 | } |
||||||
1155 | |||||||
1156 | /** |
||||||
1157 | * Take the first or last {$limit} items. |
||||||
1158 | * |
||||||
1159 | * @param int $limit |
||||||
1160 | * @return static |
||||||
1161 | */ |
||||||
1162 | public function take($limit) |
||||||
1163 | { |
||||||
1164 | if ($limit < 0) { |
||||||
1165 | return $this->passthru('take', func_get_args()); |
||||||
1166 | } |
||||||
1167 | |||||||
1168 | return new static(function () use ($limit) { |
||||||
1169 | $iterator = $this->getIterator(); |
||||||
1170 | |||||||
1171 | while ($limit--) { |
||||||
1172 | if (!$iterator->valid()) { |
||||||
1173 | break; |
||||||
1174 | } |
||||||
1175 | |||||||
1176 | yield $iterator->key() => $iterator->current(); |
||||||
1177 | |||||||
1178 | if ($limit) { |
||||||
1179 | $iterator->next(); |
||||||
1180 | } |
||||||
1181 | } |
||||||
1182 | }); |
||||||
1183 | } |
||||||
1184 | |||||||
1185 | /** |
||||||
1186 | * Take items in the collection until the given condition is met. |
||||||
1187 | * |
||||||
1188 | * @param mixed $value |
||||||
1189 | * @return static |
||||||
1190 | */ |
||||||
1191 | public function takeUntil($value) |
||||||
1192 | { |
||||||
1193 | $callback = $this->useAsCallable($value) ? $value : $this->equality($value); |
||||||
1194 | |||||||
1195 | return new static(function () use ($callback) { |
||||||
1196 | foreach ($this as $key => $item) { |
||||||
1197 | if ($callback($item, $key)) { |
||||||
1198 | break; |
||||||
1199 | } |
||||||
1200 | |||||||
1201 | yield $key => $item; |
||||||
1202 | } |
||||||
1203 | }); |
||||||
1204 | } |
||||||
1205 | |||||||
1206 | /** |
||||||
1207 | * Take items in the collection while the given condition is met. |
||||||
1208 | * |
||||||
1209 | * @param mixed $value |
||||||
1210 | * @return static |
||||||
1211 | */ |
||||||
1212 | public function takeWhile($value) |
||||||
1213 | { |
||||||
1214 | $callback = $this->useAsCallable($value) ? $value : $this->equality($value); |
||||||
1215 | |||||||
1216 | return $this->takeUntil(function ($item, $key) use ($callback) { |
||||||
1217 | return !$callback($item, $key); |
||||||
1218 | }); |
||||||
1219 | } |
||||||
1220 | |||||||
1221 | /** |
||||||
1222 | * Pass each item in the collection to the given callback, lazily. |
||||||
1223 | * |
||||||
1224 | * @param callable $callback |
||||||
1225 | * @return static |
||||||
1226 | */ |
||||||
1227 | public function tapEach(callable $callback) |
||||||
1228 | { |
||||||
1229 | return new static(function () use ($callback) { |
||||||
1230 | foreach ($this as $key => $value) { |
||||||
1231 | $callback($value, $key); |
||||||
1232 | |||||||
1233 | yield $key => $value; |
||||||
1234 | } |
||||||
1235 | }); |
||||||
1236 | } |
||||||
1237 | |||||||
1238 | /** |
||||||
1239 | * Reset the keys on the underlying array. |
||||||
1240 | * |
||||||
1241 | * @return static |
||||||
1242 | */ |
||||||
1243 | public function values() |
||||||
1244 | { |
||||||
1245 | return new static(function () { |
||||||
1246 | foreach ($this as $item) { |
||||||
1247 | yield $item; |
||||||
1248 | } |
||||||
1249 | }); |
||||||
1250 | } |
||||||
1251 | |||||||
1252 | /** |
||||||
1253 | * Zip the collection together with one or more arrays. |
||||||
1254 | * |
||||||
1255 | * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); |
||||||
1256 | * => [[1, 4], [2, 5], [3, 6]] |
||||||
1257 | * |
||||||
1258 | * @param mixed ...$items |
||||||
1259 | * @return static |
||||||
1260 | */ |
||||||
1261 | public function zip($items) |
||||||
1262 | { |
||||||
1263 | $iterables = func_get_args(); |
||||||
1264 | |||||||
1265 | return new static(function () use ($iterables) { |
||||||
1266 | $iterators = Collection::make($iterables)->map(function ($iterable) { |
||||||
1267 | return $this->makeIterator($iterable); |
||||||
1268 | })->prepend($this->getIterator()); |
||||||
1269 | |||||||
1270 | while ($iterators->contains->valid()) { |
||||||
0 ignored issues
–
show
The method
valid() does not exist on MuCTS\Collections\HigherOrderCollectionProxy . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
1271 | yield new static($iterators->map->current()); |
||||||
0 ignored issues
–
show
The method
current() does not exist on MuCTS\Collections\HigherOrderCollectionProxy . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
1272 | |||||||
1273 | $iterators->each->next(); |
||||||
0 ignored issues
–
show
The method
next() does not exist on MuCTS\Collections\HigherOrderCollectionProxy . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
1274 | } |
||||||
1275 | }); |
||||||
1276 | } |
||||||
1277 | |||||||
1278 | /** |
||||||
1279 | * Pad collection to the specified length with a value. |
||||||
1280 | * |
||||||
1281 | * @param int $size |
||||||
1282 | * @param mixed $value |
||||||
1283 | * @return static |
||||||
1284 | */ |
||||||
1285 | public function pad($size, $value) |
||||||
1286 | { |
||||||
1287 | if ($size < 0) { |
||||||
1288 | return $this->passthru('pad', func_get_args()); |
||||||
1289 | } |
||||||
1290 | |||||||
1291 | return new static(function () use ($size, $value) { |
||||||
1292 | $yielded = 0; |
||||||
1293 | |||||||
1294 | foreach ($this as $index => $item) { |
||||||
1295 | yield $index => $item; |
||||||
1296 | |||||||
1297 | $yielded++; |
||||||
1298 | } |
||||||
1299 | |||||||
1300 | while ($yielded++ < $size) { |
||||||
1301 | yield $value; |
||||||
1302 | } |
||||||
1303 | }); |
||||||
1304 | } |
||||||
1305 | |||||||
1306 | /** |
||||||
1307 | * Get the values iterator. |
||||||
1308 | * |
||||||
1309 | * @return \Traversable |
||||||
1310 | */ |
||||||
1311 | public function getIterator() |
||||||
1312 | { |
||||||
1313 | return $this->makeIterator($this->source); |
||||||
1314 | } |
||||||
1315 | |||||||
1316 | /** |
||||||
1317 | * Count the number of items in the collection. |
||||||
1318 | * |
||||||
1319 | * @return int |
||||||
1320 | */ |
||||||
1321 | public function count() |
||||||
1322 | { |
||||||
1323 | if (is_array($this->source)) { |
||||||
1324 | return count($this->source); |
||||||
1325 | } |
||||||
1326 | |||||||
1327 | return iterator_count($this->getIterator()); |
||||||
1328 | } |
||||||
1329 | |||||||
1330 | /** |
||||||
1331 | * Make an iterator from the given source. |
||||||
1332 | * |
||||||
1333 | * @param mixed $source |
||||||
1334 | * @return \Traversable |
||||||
1335 | */ |
||||||
1336 | protected function makeIterator($source) |
||||||
1337 | { |
||||||
1338 | if ($source instanceof IteratorAggregate) { |
||||||
1339 | return $source->getIterator(); |
||||||
1340 | } |
||||||
1341 | |||||||
1342 | if (is_array($source)) { |
||||||
1343 | return new ArrayIterator($source); |
||||||
1344 | } |
||||||
1345 | |||||||
1346 | return $source(); |
||||||
1347 | } |
||||||
1348 | |||||||
1349 | /** |
||||||
1350 | * Explode the "value" and "key" arguments passed to "pluck". |
||||||
1351 | * |
||||||
1352 | * @param string|array $value |
||||||
1353 | * @param string|array|null $key |
||||||
1354 | * @return array |
||||||
1355 | */ |
||||||
1356 | protected function explodePluckParameters($value, $key) |
||||||
1357 | { |
||||||
1358 | $value = is_string($value) ? explode('.', $value) : $value; |
||||||
1359 | |||||||
1360 | $key = is_null($key) || is_array($key) ? $key : explode('.', $key); |
||||||
1361 | |||||||
1362 | return [$value, $key]; |
||||||
1363 | } |
||||||
1364 | |||||||
1365 | /** |
||||||
1366 | * Pass this lazy collection through a method on the collection class. |
||||||
1367 | * |
||||||
1368 | * @param string $method |
||||||
1369 | * @param array $params |
||||||
1370 | * @return static |
||||||
1371 | */ |
||||||
1372 | protected function passthru($method, array $params) |
||||||
1373 | { |
||||||
1374 | return new static(function () use ($method, $params) { |
||||||
1375 | yield from $this->collect()->$method(...$params); |
||||||
1376 | }); |
||||||
1377 | } |
||||||
1378 | } |
||||||
1379 |