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