1: | <?php declare(strict_types=1); |
2: | |
3: | namespace Salient\Contract\Collection; |
4: | |
5: | use Salient\Contract\Core\Arrayable; |
6: | use Salient\Contract\Core\Jsonable; |
7: | use ArrayAccess; |
8: | use Countable; |
9: | use IteratorAggregate; |
10: | use JsonSerializable; |
11: | use OutOfRangeException; |
12: | |
13: | /** |
14: | * @api |
15: | * |
16: | * @template TKey of array-key |
17: | * @template TValue |
18: | * |
19: | * @extends ArrayAccess<TKey,TValue> |
20: | * @extends Arrayable<TKey,TValue|mixed[]> |
21: | * @extends IteratorAggregate<TKey,TValue> |
22: | */ |
23: | interface CollectionInterface extends |
24: | ArrayAccess, |
25: | Arrayable, |
26: | Countable, |
27: | IteratorAggregate, |
28: | JsonSerializable, |
29: | Jsonable |
30: | { |
31: | /** |
32: | * Pass the value of each item to the callback |
33: | */ |
34: | public const CALLBACK_USE_VALUE = 1; |
35: | |
36: | /** |
37: | * Pass the key of each item to the callback |
38: | */ |
39: | public const CALLBACK_USE_KEY = 2; |
40: | |
41: | /** |
42: | * Pass a key-value pair to the callback for each item |
43: | */ |
44: | public const CALLBACK_USE_BOTH = 3; |
45: | |
46: | /** |
47: | * Return the first item that satisfies the callback |
48: | */ |
49: | public const FIND_VALUE = 8; |
50: | |
51: | /** |
52: | * Return the key of the first item that satisfies the callback |
53: | */ |
54: | public const FIND_KEY = 16; |
55: | |
56: | /** |
57: | * @param Arrayable<TKey,TValue>|iterable<TKey,TValue> $items |
58: | */ |
59: | public function __construct($items = []); |
60: | |
61: | /** |
62: | * Check if the collection is empty |
63: | * |
64: | * @phpstan-assert-if-false non-empty-array<TKey,TValue> $this->all() |
65: | * @phpstan-assert-if-false !null $this->first() |
66: | * @phpstan-assert-if-false !null $this->last() |
67: | */ |
68: | public function isEmpty(): bool; |
69: | |
70: | /** |
71: | * Add or replace an item with a given key |
72: | * |
73: | * @param TKey $key |
74: | * @param TValue $value |
75: | * @return static |
76: | */ |
77: | public function set($key, $value); |
78: | |
79: | /** |
80: | * Check if an item with a given key exists |
81: | * |
82: | * @param TKey $key |
83: | * @phpstan-assert-if-true non-empty-array<TKey,TValue> $this->all() |
84: | * @phpstan-assert-if-true !null $this->first() |
85: | * @phpstan-assert-if-true !null $this->last() |
86: | */ |
87: | public function has($key): bool; |
88: | |
89: | /** |
90: | * Get the item with the given key |
91: | * |
92: | * @param TKey $key |
93: | * @return TValue |
94: | * @throws OutOfRangeException if there is no such item in the collection. |
95: | */ |
96: | public function get($key); |
97: | |
98: | /** |
99: | * Remove an item with a given key |
100: | * |
101: | * @param TKey $key |
102: | * @return static |
103: | */ |
104: | public function unset($key); |
105: | |
106: | /** |
107: | * Add an item |
108: | * |
109: | * @param TValue $value |
110: | * @return static |
111: | */ |
112: | public function add($value); |
113: | |
114: | /** |
115: | * Merge the collection with the given items |
116: | * |
117: | * @param Arrayable<TKey,TValue>|iterable<TKey,TValue> $items |
118: | * @return static |
119: | */ |
120: | public function merge($items); |
121: | |
122: | /** |
123: | * Sort items in the collection |
124: | * |
125: | * @return static |
126: | */ |
127: | public function sort(); |
128: | |
129: | /** |
130: | * Reverse the order of items in the collection |
131: | * |
132: | * @return static |
133: | */ |
134: | public function reverse(); |
135: | |
136: | /** |
137: | * Pass each item in the collection to a callback |
138: | * |
139: | * The callback's return values are discarded. |
140: | * |
141: | * @template TMode of int-mask-of<CollectionInterface::*> |
142: | * |
143: | * @param (callable(TValue, TValue|null $next, TValue|null $prev): mixed)|(callable(TKey, TKey|null $next, TKey|null $prev): mixed)|(callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): mixed) $callback |
144: | * @phpstan-param ( |
145: | * TMode is 3|11|19 |
146: | * ? (callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): mixed) |
147: | * : (TMode is 2|10|18 |
148: | * ? (callable(TKey, TKey|null $next, TKey|null $prev): mixed) |
149: | * : (callable(TValue, TValue|null $next, TValue|null $prev): mixed) |
150: | * ) |
151: | * ) $callback |
152: | * @param TMode $mode |
153: | * @return $this |
154: | */ |
155: | public function forEach(callable $callback, int $mode = CollectionInterface::CALLBACK_USE_VALUE); |
156: | |
157: | /** |
158: | * Pass each item in the collection to a callback and populate a new |
159: | * collection with its return values |
160: | * |
161: | * @template TMode of int-mask-of<CollectionInterface::*> |
162: | * |
163: | * @param (callable(TValue, TValue|null $next, TValue|null $prev): TValue)|(callable(TKey, TKey|null $next, TKey|null $prev): TValue)|(callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): TValue) $callback |
164: | * @phpstan-param ( |
165: | * TMode is 3|11|19 |
166: | * ? (callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): TValue) |
167: | * : (TMode is 2|10|18 |
168: | * ? (callable(TKey, TKey|null $next, TKey|null $prev): TValue) |
169: | * : (callable(TValue, TValue|null $next, TValue|null $prev): TValue) |
170: | * ) |
171: | * ) $callback |
172: | * @param TMode $mode |
173: | * @return static |
174: | */ |
175: | public function map(callable $callback, int $mode = CollectionInterface::CALLBACK_USE_VALUE); |
176: | |
177: | /** |
178: | * Reduce the collection to items that satisfy a callback |
179: | * |
180: | * @template TMode of int-mask-of<CollectionInterface::*> |
181: | * |
182: | * @param (callable(TValue, TValue|null $next, TValue|null $prev): bool)|(callable(TKey, TKey|null $next, TKey|null $prev): bool)|(callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): bool) $callback |
183: | * @phpstan-param ( |
184: | * TMode is 3|11|19 |
185: | * ? (callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): bool) |
186: | * : (TMode is 2|10|18 |
187: | * ? (callable(TKey, TKey|null $next, TKey|null $prev): bool) |
188: | * : (callable(TValue, TValue|null $next, TValue|null $prev): bool) |
189: | * ) |
190: | * ) $callback |
191: | * @param TMode $mode |
192: | * @return static |
193: | */ |
194: | public function filter(callable $callback, int $mode = CollectionInterface::CALLBACK_USE_VALUE); |
195: | |
196: | /** |
197: | * Get the first item that satisfies a callback, or null if there is no such |
198: | * item in the collection |
199: | * |
200: | * @template TMode of int-mask-of<CollectionInterface::*> |
201: | * |
202: | * @param (callable(TValue, TValue|null $next, TValue|null $prev): bool)|(callable(TKey, TKey|null $next, TKey|null $prev): bool)|(callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): bool) $callback |
203: | * @phpstan-param ( |
204: | * TMode is 3|11|19 |
205: | * ? (callable(array{TKey,TValue}, array{TKey,TValue}|null $next, array{TKey,TValue}|null $prev): bool) |
206: | * : (TMode is 2|10|18 |
207: | * ? (callable(TKey, TKey|null $next, TKey|null $prev): bool) |
208: | * : (callable(TValue, TValue|null $next, TValue|null $prev): bool) |
209: | * ) |
210: | * ) $callback |
211: | * @param TMode $mode |
212: | * @return (TMode is 16|17|18|19 ? TKey : TValue)|null |
213: | */ |
214: | public function find(callable $callback, int $mode = CollectionInterface::CALLBACK_USE_VALUE | CollectionInterface::FIND_VALUE); |
215: | |
216: | /** |
217: | * Reduce the collection to items with keys in an array |
218: | * |
219: | * @param TKey[] $keys |
220: | * @return static |
221: | */ |
222: | public function only(array $keys); |
223: | |
224: | /** |
225: | * Reduce the collection to items with keys in an index |
226: | * |
227: | * @param array<TKey,true> $index |
228: | * @return static |
229: | */ |
230: | public function onlyIn(array $index); |
231: | |
232: | /** |
233: | * Reduce the collection to items with keys not in an array |
234: | * |
235: | * @param TKey[] $keys |
236: | * @return static |
237: | */ |
238: | public function except(array $keys); |
239: | |
240: | /** |
241: | * Reduce the collection to items with keys not in an index |
242: | * |
243: | * @param array<TKey,true> $index |
244: | * @return static |
245: | */ |
246: | public function exceptIn(array $index); |
247: | |
248: | /** |
249: | * Extract a slice of the collection |
250: | * |
251: | * @return static |
252: | */ |
253: | public function slice(int $offset, ?int $length = null); |
254: | |
255: | /** |
256: | * Check if a value is in the collection |
257: | * |
258: | * @param TValue $value |
259: | * @phpstan-assert-if-true non-empty-array<TKey,TValue> $this->all() |
260: | * @phpstan-assert-if-true !null $this->first() |
261: | * @phpstan-assert-if-true !null $this->last() |
262: | */ |
263: | public function hasValue($value, bool $strict = false): bool; |
264: | |
265: | /** |
266: | * Get the first key at which a value is found, or null if it's not in the |
267: | * collection |
268: | * |
269: | * @param TValue $value |
270: | * @return TKey|null |
271: | */ |
272: | public function keyOf($value, bool $strict = false); |
273: | |
274: | /** |
275: | * Get the first item equal but not necessarily identical to a value, or |
276: | * null if it's not in the collection |
277: | * |
278: | * @param TValue $value |
279: | * @return TValue|null |
280: | */ |
281: | public function firstOf($value); |
282: | |
283: | /** |
284: | * Get all items in the collection |
285: | * |
286: | * @return array<TKey,TValue> |
287: | */ |
288: | public function all(): array; |
289: | |
290: | /** |
291: | * Get the first item, or null if the collection is empty |
292: | * |
293: | * @return TValue|null |
294: | */ |
295: | public function first(); |
296: | |
297: | /** |
298: | * Get the last item, or null if the collection is empty |
299: | * |
300: | * @return TValue|null |
301: | */ |
302: | public function last(); |
303: | |
304: | /** |
305: | * Get the nth item (1-based), or null if there is no such item in the |
306: | * collection |
307: | * |
308: | * If `$n` is negative, the nth item from the end of the collection is |
309: | * returned. |
310: | * |
311: | * @return TValue|null |
312: | */ |
313: | public function nth(int $n); |
314: | |
315: | /** |
316: | * Push items onto the end of the collection |
317: | * |
318: | * @param TValue ...$items |
319: | * @return static |
320: | */ |
321: | public function push(...$items); |
322: | |
323: | /** |
324: | * Pop an item off the end of the collection |
325: | * |
326: | * @param TValue|null $last Receives the value removed from the collection, |
327: | * or `null` if the collection is empty. |
328: | * @return static |
329: | */ |
330: | public function pop(&$last = null); |
331: | |
332: | /** |
333: | * Shift an item off the beginning of the collection |
334: | * |
335: | * @param TValue|null $first Receives the value removed from the collection, |
336: | * or `null` if the collection is empty. |
337: | * @return static |
338: | */ |
339: | public function shift(&$first = null); |
340: | |
341: | /** |
342: | * Add items to the beginning of the collection |
343: | * |
344: | * Items are added in one operation and stay in the given order. |
345: | * |
346: | * @param TValue ...$items |
347: | * @return static |
348: | */ |
349: | public function unshift(...$items); |
350: | } |
351: |