1: <?php declare(strict_types=1);
2:
3: namespace Salient\Iterator\Concern;
4:
5: use Salient\Contract\Iterator\FluentIteratorInterface;
6: use ArrayAccess;
7:
8: /**
9: * Implements FluentIteratorInterface
10: *
11: * @see FluentIteratorInterface
12: *
13: * @api
14: *
15: * @template TKey of array-key
16: * @template TValue
17: *
18: * @phpstan-require-implements FluentIteratorInterface
19: */
20: trait FluentIteratorTrait
21: {
22: /**
23: * @return ($preserveKeys is true ? array<TKey,TValue> : list<TValue>)
24: */
25: public function toArray(bool $preserveKeys = true): array
26: {
27: if ($preserveKeys) {
28: foreach ($this as $key => $value) {
29: $array[$key] = $value;
30: }
31: } else {
32: foreach ($this as $value) {
33: $array[] = $value;
34: }
35: }
36: return $array ?? [];
37: }
38:
39: /**
40: * @param callable(TValue, TKey): mixed $callback
41: * @return $this
42: */
43: public function forEach(callable $callback)
44: {
45: foreach ($this as $key => $value) {
46: $callback($value, $key);
47: }
48: return $this;
49: }
50:
51: /**
52: * @param array-key $key
53: * @param mixed $value
54: * @return TValue|null
55: */
56: public function nextWithValue($key, $value, bool $strict = false)
57: {
58: foreach ($this as $current) {
59: // Move forward-only iterators to the next element
60: if (isset($found)) {
61: break;
62: }
63: if (is_array($current) || $current instanceof ArrayAccess) {
64: $_value = $current[$key];
65: } else {
66: $_value = $current->$key;
67: }
68: if ($strict) {
69: if ($_value === $value) {
70: $found = $current;
71: }
72: } elseif ($_value == $value) {
73: $found = $current;
74: }
75: }
76: return $found ?? null;
77: }
78: }
79: