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: