@daiso-tech/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.changeset/sweet-peas-beg.md +5 -0
  4. package/.eslintignore +3 -0
  5. package/.eslintrc.json +50 -0
  6. package/.gitattributes +6 -0
  7. package/.github/workflows/main.yaml +54 -0
  8. package/.github/workflows/release.yaml +31 -0
  9. package/.prettierignore +4 -0
  10. package/.prettierrc.json +4 -0
  11. package/.vscode/settings.json +46 -0
  12. package/LICENSE.md +194 -0
  13. package/docs-api/.nojekyll +1 -0
  14. package/docs-api/assets/highlight.css +92 -0
  15. package/docs-api/assets/icons.js +18 -0
  16. package/docs-api/assets/icons.svg +1 -0
  17. package/docs-api/assets/main.js +60 -0
  18. package/docs-api/assets/navigation.js +1 -0
  19. package/docs-api/assets/search.js +1 -0
  20. package/docs-api/assets/style.css +1448 -0
  21. package/docs-api/classes/AsyncIterableCollection.html +437 -0
  22. package/docs-api/classes/CollectionError.html +12 -0
  23. package/docs-api/classes/IndexOverflowError.html +12 -0
  24. package/docs-api/classes/ItemNotFoundError.html +12 -0
  25. package/docs-api/classes/IterableCollection.html +434 -0
  26. package/docs-api/classes/ListCollection.html +434 -0
  27. package/docs-api/classes/MultipleItemsFoundError.html +12 -0
  28. package/docs-api/classes/UnexpectedCollectionError.html +12 -0
  29. package/docs-api/functions/isAsyncIterable.html +1 -0
  30. package/docs-api/functions/isIterable.html +1 -0
  31. package/docs-api/functions/range.html +4 -0
  32. package/docs-api/hierarchy.html +1 -0
  33. package/docs-api/index.html +1 -0
  34. package/docs-api/modules.html +60 -0
  35. package/docs-api/types/AsyncCollapse.html +1 -0
  36. package/docs-api/types/AsyncFilter.html +1 -0
  37. package/docs-api/types/AsyncFilter_.html +1 -0
  38. package/docs-api/types/AsyncFindOrSettings.html +1 -0
  39. package/docs-api/types/AsyncFindSettings.html +1 -0
  40. package/docs-api/types/AsyncForEach.html +1 -0
  41. package/docs-api/types/AsyncForEach_.html +1 -0
  42. package/docs-api/types/AsyncGroupBySettings.html +1 -0
  43. package/docs-api/types/AsyncIterableValue.html +1 -0
  44. package/docs-api/types/AsyncLazyable.html +1 -0
  45. package/docs-api/types/AsyncLazyable_.html +1 -0
  46. package/docs-api/types/AsyncMap.html +1 -0
  47. package/docs-api/types/AsyncMap_.html +1 -0
  48. package/docs-api/types/AsyncModifier.html +1 -0
  49. package/docs-api/types/AsyncModifier_.html +1 -0
  50. package/docs-api/types/AsyncReduce.html +1 -0
  51. package/docs-api/types/AsyncReduceSettings.html +1 -0
  52. package/docs-api/types/AsyncReduce_.html +1 -0
  53. package/docs-api/types/AsyncTap.html +1 -0
  54. package/docs-api/types/AsyncTap_.html +1 -0
  55. package/docs-api/types/AsyncTransform.html +1 -0
  56. package/docs-api/types/AsyncTransform_.html +1 -0
  57. package/docs-api/types/Collapse.html +1 -0
  58. package/docs-api/types/Comparator.html +1 -0
  59. package/docs-api/types/EnsureType.html +1 -0
  60. package/docs-api/types/Filter.html +1 -0
  61. package/docs-api/types/FilterGuard.html +1 -0
  62. package/docs-api/types/Filter_.html +1 -0
  63. package/docs-api/types/FindOrSettings.html +1 -0
  64. package/docs-api/types/FindSettings.html +1 -0
  65. package/docs-api/types/ForEach.html +1 -0
  66. package/docs-api/types/GroupBySettings.html +1 -0
  67. package/docs-api/types/IAsyncCollection.html +357 -0
  68. package/docs-api/types/ICollection.html +357 -0
  69. package/docs-api/types/JoinSettings.html +1 -0
  70. package/docs-api/types/Lazyable.html +1 -0
  71. package/docs-api/types/Map.html +1 -0
  72. package/docs-api/types/Modifier.html +1 -0
  73. package/docs-api/types/PageSettings.html +1 -0
  74. package/docs-api/types/RecordItem.html +1 -0
  75. package/docs-api/types/Reduce.html +1 -0
  76. package/docs-api/types/ReduceSettings.html +1 -0
  77. package/docs-api/types/ReverseSettings.html +1 -0
  78. package/docs-api/types/SliceSettings.html +1 -0
  79. package/docs-api/types/SlidingSettings.html +1 -0
  80. package/docs-api/types/Tap.html +1 -0
  81. package/docs-api/types/Transform.html +1 -0
  82. package/docs-api/types/UpdatedItem.html +1 -0
  83. package/package.json +47 -0
  84. package/src/_module.ts +2 -0
  85. package/src/collection/_module.ts +4 -0
  86. package/src/collection/_shared.ts +45 -0
  87. package/src/collection/async-iterable-collection/_module.ts +1 -0
  88. package/src/collection/async-iterable-collection/async-iterable-collection.test.ts +3195 -0
  89. package/src/collection/async-iterable-collection/async-iterable-collection.ts +1276 -0
  90. package/src/collection/async-iterable-collection/async-iterable-helpers/_module.ts +35 -0
  91. package/src/collection/async-iterable-collection/async-iterable-helpers/async-abort-iterable.ts +25 -0
  92. package/src/collection/async-iterable-collection/async-iterable-helpers/async-chunk-iterable.ts +57 -0
  93. package/src/collection/async-iterable-collection/async-iterable-helpers/async-chunk-whilte-iterable.ts +54 -0
  94. package/src/collection/async-iterable-collection/async-iterable-helpers/async-collapse-iterable.ts +40 -0
  95. package/src/collection/async-iterable-collection/async-iterable-helpers/async-count-by-iterable.ts +58 -0
  96. package/src/collection/async-iterable-collection/async-iterable-helpers/async-cross-join-iterable.ts +69 -0
  97. package/src/collection/async-iterable-collection/async-iterable-helpers/async-delay-iterable.ts +19 -0
  98. package/src/collection/async-iterable-collection/async-iterable-helpers/async-entries-iterable.ts +28 -0
  99. package/src/collection/async-iterable-collection/async-iterable-helpers/async-filter-iterable.ts +42 -0
  100. package/src/collection/async-iterable-collection/async-iterable-helpers/async-flat-map-iterable.ts +44 -0
  101. package/src/collection/async-iterable-collection/async-iterable-helpers/async-group-by-iterable.ts +48 -0
  102. package/src/collection/async-iterable-collection/async-iterable-helpers/async-insert-after-iterable.ts +57 -0
  103. package/src/collection/async-iterable-collection/async-iterable-helpers/async-insert-before-iterable.ts +57 -0
  104. package/src/collection/async-iterable-collection/async-iterable-helpers/async-map-iterable.ts +40 -0
  105. package/src/collection/async-iterable-collection/async-iterable-helpers/async-merge-iterable.ts +35 -0
  106. package/src/collection/async-iterable-collection/async-iterable-helpers/async-pad-end-iterable.ts +41 -0
  107. package/src/collection/async-iterable-collection/async-iterable-helpers/async-pad-start-iterable.ts +41 -0
  108. package/src/collection/async-iterable-collection/async-iterable-helpers/async-partion-iterable.ts +63 -0
  109. package/src/collection/async-iterable-collection/async-iterable-helpers/async-repeat-iterable.ts +40 -0
  110. package/src/collection/async-iterable-collection/async-iterable-helpers/async-reverse-iterable.ts +35 -0
  111. package/src/collection/async-iterable-collection/async-iterable-helpers/async-shuffle-iterable.ts +23 -0
  112. package/src/collection/async-iterable-collection/async-iterable-helpers/async-skip-iterable.ts +41 -0
  113. package/src/collection/async-iterable-collection/async-iterable-helpers/async-skip-until-iterable.ts +55 -0
  114. package/src/collection/async-iterable-collection/async-iterable-helpers/async-slice-iterable.ts +33 -0
  115. package/src/collection/async-iterable-collection/async-iterable-helpers/async-sliding-iterable.ts +54 -0
  116. package/src/collection/async-iterable-collection/async-iterable-helpers/async-sort-iterable.ts +18 -0
  117. package/src/collection/async-iterable-collection/async-iterable-helpers/async-split-iterable.ts +64 -0
  118. package/src/collection/async-iterable-collection/async-iterable-helpers/async-take-iterable.ts +41 -0
  119. package/src/collection/async-iterable-collection/async-iterable-helpers/async-take-until-iterable.ts +41 -0
  120. package/src/collection/async-iterable-collection/async-iterable-helpers/async-tap-iterable.ts +34 -0
  121. package/src/collection/async-iterable-collection/async-iterable-helpers/async-timeout-iterable.ts +20 -0
  122. package/src/collection/async-iterable-collection/async-iterable-helpers/async-unique-iterable.ts +49 -0
  123. package/src/collection/async-iterable-collection/async-iterable-helpers/async-update-iterable.ts +64 -0
  124. package/src/collection/async-iterable-collection/async-iterable-helpers/async-when-iterable.ts +43 -0
  125. package/src/collection/async-iterable-collection/async-iterable-helpers/async-zip-iterable.ts +45 -0
  126. package/src/collection/iterable-collection/_module.ts +1 -0
  127. package/src/collection/iterable-collection/iterable-collection.test.ts +2379 -0
  128. package/src/collection/iterable-collection/iterable-collection.ts +1317 -0
  129. package/src/collection/iterable-collection/iterable-helpers/_module.ts +32 -0
  130. package/src/collection/iterable-collection/iterable-helpers/chunk-iterable.ts +49 -0
  131. package/src/collection/iterable-collection/iterable-helpers/chunk-whilte-iterable.ts +51 -0
  132. package/src/collection/iterable-collection/iterable-helpers/collapse-iterable.ts +35 -0
  133. package/src/collection/iterable-collection/iterable-helpers/count-by-iterable.ts +49 -0
  134. package/src/collection/iterable-collection/iterable-helpers/cross-join-iterable.ts +57 -0
  135. package/src/collection/iterable-collection/iterable-helpers/entries-iterable.ts +42 -0
  136. package/src/collection/iterable-collection/iterable-helpers/filter-iterable.ts +39 -0
  137. package/src/collection/iterable-collection/iterable-helpers/flat-map-iterable.ts +35 -0
  138. package/src/collection/iterable-collection/iterable-helpers/group-by-iterable.ts +52 -0
  139. package/src/collection/iterable-collection/iterable-helpers/insert-after-iterable.ts +43 -0
  140. package/src/collection/iterable-collection/iterable-helpers/insert-before-iterable.ts +43 -0
  141. package/src/collection/iterable-collection/iterable-helpers/map-iterable.ts +35 -0
  142. package/src/collection/iterable-collection/iterable-helpers/merge-iterable.ts +31 -0
  143. package/src/collection/iterable-collection/iterable-helpers/pad-end-iterable.ts +52 -0
  144. package/src/collection/iterable-collection/iterable-helpers/pad-start-iterable.ts +52 -0
  145. package/src/collection/iterable-collection/iterable-helpers/partion-iterable.ts +46 -0
  146. package/src/collection/iterable-collection/iterable-helpers/repeat-iterable.ts +36 -0
  147. package/src/collection/iterable-collection/iterable-helpers/reverse-iterable.ts +46 -0
  148. package/src/collection/iterable-collection/iterable-helpers/shuffle-iterable.ts +36 -0
  149. package/src/collection/iterable-collection/iterable-helpers/skip-iterable.ts +37 -0
  150. package/src/collection/iterable-collection/iterable-helpers/skip-until-iterable.ts +41 -0
  151. package/src/collection/iterable-collection/iterable-helpers/slice-iterable.ts +47 -0
  152. package/src/collection/iterable-collection/iterable-helpers/sliding-iterable.ts +49 -0
  153. package/src/collection/iterable-collection/iterable-helpers/sort-iterable.ts +29 -0
  154. package/src/collection/iterable-collection/iterable-helpers/split-iterable.ts +58 -0
  155. package/src/collection/iterable-collection/iterable-helpers/take-iterable.ts +37 -0
  156. package/src/collection/iterable-collection/iterable-helpers/take-until-iterable.ts +38 -0
  157. package/src/collection/iterable-collection/iterable-helpers/tap-iterable.ts +31 -0
  158. package/src/collection/iterable-collection/iterable-helpers/unique-iterable.ts +43 -0
  159. package/src/collection/iterable-collection/iterable-helpers/update-iterable.ts +50 -0
  160. package/src/collection/iterable-collection/iterable-helpers/when-iterable.ts +37 -0
  161. package/src/collection/iterable-collection/iterable-helpers/zip-iterable.ts +41 -0
  162. package/src/collection/list-collection/_module.ts +1 -0
  163. package/src/collection/list-collection/list-collection.test.ts +2280 -0
  164. package/src/collection/list-collection/list-collection.ts +1883 -0
  165. package/src/contracts/_module.ts +1 -0
  166. package/src/contracts/collection/_module.ts +3 -0
  167. package/src/contracts/collection/_shared.ts +346 -0
  168. package/src/contracts/collection/async-collection.contract.ts +1028 -0
  169. package/src/contracts/collection/collection.contract.ts +978 -0
  170. package/src/types.ts +2 -0
  171. package/tsconfig.base.json +31 -0
  172. package/tsconfig.cjs.json +12 -0
  173. package/tsconfig.esm.json +12 -0
  174. package/tsconfig.json +10 -0
  175. package/tsconfig.types.json +12 -0
  176. package/vite.config.ts +6 -0
@@ -0,0 +1,1883 @@
1
+ import { isIterable } from "@/collection/_shared";
2
+ import {
3
+ type Collapse,
4
+ CollectionError,
5
+ type Comparator,
6
+ type Filter,
7
+ type FindOrSettings,
8
+ type FindSettings,
9
+ type ForEach,
10
+ type GroupBySettings,
11
+ type ICollection,
12
+ ItemNotFoundError,
13
+ type JoinSettings,
14
+ type Lazyable,
15
+ type Map,
16
+ type Modifier,
17
+ MultipleItemsFoundError,
18
+ type PageSettings,
19
+ type RecordItem,
20
+ type ReduceSettings,
21
+ type ReverseSettings,
22
+ type SliceSettings,
23
+ type SlidingSettings,
24
+ type Tap,
25
+ type Transform,
26
+ UnexpectedCollectionError,
27
+ type UpdatedItem,
28
+ } from "@/contracts/collection/_module";
29
+ import { EnsureType } from "@/types";
30
+
31
+ /**
32
+ * All methods in ListCollection are eager and therefore will run immediately.
33
+ * @group Collections
34
+ */
35
+ export class ListCollection<TInput> implements ICollection<TInput> {
36
+ private array: TInput[];
37
+
38
+ constructor(iterable: Iterable<TInput>) {
39
+ this.array = [...iterable];
40
+ }
41
+
42
+ *[Symbol.iterator](): Iterator<TInput> {
43
+ yield* this.array;
44
+ }
45
+
46
+ iterator(): Iterator<TInput, void> {
47
+ return this[Symbol.iterator]() as Iterator<TInput, void>;
48
+ }
49
+
50
+ entries(
51
+ _throwOnNumberLimit?: boolean,
52
+ ): ICollection<RecordItem<number, TInput>> {
53
+ try {
54
+ return new ListCollection(this.array.entries());
55
+ } catch (error: unknown) {
56
+ if (
57
+ error instanceof CollectionError ||
58
+ error instanceof TypeError
59
+ ) {
60
+ throw error;
61
+ }
62
+ throw new UnexpectedCollectionError(
63
+ `Unexpected error "${String(error)}" occured`,
64
+ error,
65
+ );
66
+ }
67
+ }
68
+
69
+ keys(_throwOnNumberLimit?: boolean): ICollection<number> {
70
+ try {
71
+ return new ListCollection(this.array.keys());
72
+ } catch (error: unknown) {
73
+ if (
74
+ error instanceof CollectionError ||
75
+ error instanceof TypeError
76
+ ) {
77
+ throw error;
78
+ }
79
+ throw new UnexpectedCollectionError(
80
+ `Unexpected error "${String(error)}" occured`,
81
+ error,
82
+ );
83
+ }
84
+ }
85
+
86
+ values(): ICollection<TInput> {
87
+ return new ListCollection(this);
88
+ }
89
+
90
+ filter<TOutput extends TInput>(
91
+ filter: Filter<TInput, ICollection<TInput>, TOutput>,
92
+ _throwOnNumberLimit?: boolean,
93
+ ): ICollection<TOutput> {
94
+ try {
95
+ return new ListCollection(
96
+ this.array.filter((item, index) =>
97
+ filter(item, index, this),
98
+ ) as TOutput[],
99
+ );
100
+ } catch (error: unknown) {
101
+ if (
102
+ error instanceof CollectionError ||
103
+ error instanceof TypeError
104
+ ) {
105
+ throw error;
106
+ }
107
+ throw new UnexpectedCollectionError(
108
+ `Unexpected error "${String(error)}" occured`,
109
+ error,
110
+ );
111
+ }
112
+ }
113
+
114
+ map<TOutput>(
115
+ map: Map<TInput, ICollection<TInput>, TOutput>,
116
+ _throwOnNumberLimit?: boolean,
117
+ ): ICollection<TOutput> {
118
+ try {
119
+ return new ListCollection(
120
+ this.array.map((item, index) => map(item, index, this)),
121
+ );
122
+ } catch (error: unknown) {
123
+ if (
124
+ error instanceof CollectionError ||
125
+ error instanceof TypeError
126
+ ) {
127
+ throw error;
128
+ }
129
+ throw new UnexpectedCollectionError(
130
+ `Unexpected error "${String(error)}" occured`,
131
+ error,
132
+ );
133
+ }
134
+ }
135
+
136
+ reduce<TOutput = TInput>(
137
+ settings: ReduceSettings<TInput, ICollection<TInput>, TOutput>,
138
+ ): TOutput {
139
+ try {
140
+ if (settings.initialValue === undefined && this.empty()) {
141
+ throw new TypeError(
142
+ "Reduce of empty array must be inputed a initial value",
143
+ );
144
+ }
145
+ if (settings.initialValue !== undefined) {
146
+ return this.array.reduce<TOutput>(
147
+ (initialValue, item, index) =>
148
+ settings.reduceFn(initialValue, item, index, this),
149
+ settings.initialValue,
150
+ );
151
+ }
152
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
153
+ return this.array.reduce((initialValue, item, index) => {
154
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
155
+ const reduce = settings.reduceFn as any;
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
157
+ return reduce(initialValue, item, index, this);
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ }) as any;
160
+ } catch (error: unknown) {
161
+ if (
162
+ error instanceof CollectionError ||
163
+ error instanceof TypeError
164
+ ) {
165
+ throw error;
166
+ }
167
+ throw new UnexpectedCollectionError(
168
+ `Unexpected error "${String(error)}" occured`,
169
+ error,
170
+ );
171
+ }
172
+ }
173
+
174
+ join(settings?: JoinSettings): string {
175
+ try {
176
+ return this.reduce({
177
+ reduceFn(str, item) {
178
+ if (typeof item !== "string") {
179
+ throw new TypeError(
180
+ "Item type is invalid must be string",
181
+ );
182
+ }
183
+ const separator = settings?.seperator ?? ",";
184
+ return str + separator + item;
185
+ },
186
+ });
187
+ } catch (error: unknown) {
188
+ if (
189
+ error instanceof CollectionError ||
190
+ error instanceof TypeError
191
+ ) {
192
+ throw error;
193
+ }
194
+ throw new UnexpectedCollectionError(
195
+ `Unexpected error "${String(error)}" occured`,
196
+ error,
197
+ );
198
+ }
199
+ }
200
+
201
+ collapse(): ICollection<Collapse<TInput>> {
202
+ const items: TInput[] = [];
203
+ try {
204
+ for (const item of this.array) {
205
+ if (isIterable<TInput>(item)) {
206
+ items.push(...items);
207
+ } else {
208
+ items.push(item);
209
+ }
210
+ }
211
+ return new ListCollection(items as Collapse<TInput>[]);
212
+ } catch (error: unknown) {
213
+ if (
214
+ error instanceof CollectionError ||
215
+ error instanceof TypeError
216
+ ) {
217
+ throw error;
218
+ }
219
+ throw new UnexpectedCollectionError(
220
+ `Unexpected error "${String(error)}" occured`,
221
+ error,
222
+ );
223
+ }
224
+ }
225
+
226
+ flatMap<TOutput>(
227
+ map: Map<TInput, ICollection<TInput>, Iterable<TOutput>>,
228
+ _throwOnNumberLimit?: boolean,
229
+ ): ICollection<TOutput> {
230
+ try {
231
+ return new ListCollection(
232
+ this.array.flatMap((item, index) => [
233
+ ...map(item, index, this),
234
+ ]),
235
+ );
236
+ } catch (error: unknown) {
237
+ if (
238
+ error instanceof CollectionError ||
239
+ error instanceof TypeError
240
+ ) {
241
+ throw error;
242
+ }
243
+ throw new UnexpectedCollectionError(
244
+ `Unexpected error "${String(error)}" occured`,
245
+ error,
246
+ );
247
+ }
248
+ }
249
+
250
+ update<TFilterOutput extends TInput, TMapOutput>(
251
+ filter: Filter<TInput, ICollection<TInput>, TFilterOutput>,
252
+ map: Map<TFilterOutput, ICollection<TInput>, TMapOutput>,
253
+ _throwOnNumberLimit?: boolean,
254
+ ): ICollection<UpdatedItem<TInput, TFilterOutput, TMapOutput>> {
255
+ try {
256
+ return new ListCollection(
257
+ this.array.map((item, index) => {
258
+ if (filter(item, index, this)) {
259
+ return map(item as TFilterOutput, index, this);
260
+ }
261
+ return item;
262
+ }),
263
+ );
264
+ } catch (error: unknown) {
265
+ if (
266
+ error instanceof CollectionError ||
267
+ error instanceof TypeError
268
+ ) {
269
+ throw error;
270
+ }
271
+ throw new UnexpectedCollectionError(
272
+ `Unexpected error "${String(error)}" occured`,
273
+ error,
274
+ );
275
+ }
276
+ }
277
+
278
+ page(settings: PageSettings): ICollection<TInput> {
279
+ const { page, pageSize } = settings;
280
+ if (page < 0) {
281
+ return this.skip(page * pageSize).take(pageSize);
282
+ }
283
+ return this.skip((page - 1) * pageSize).take(page * pageSize);
284
+ }
285
+
286
+ sum(_throwOnNumberLimit?: boolean): EnsureType<TInput, number> {
287
+ return this.reduce({
288
+ reduceFn: (sum, item) => {
289
+ if (typeof item !== "number") {
290
+ throw new TypeError("Item type is invalid must be number");
291
+ }
292
+ return sum + item;
293
+ },
294
+ initialValue: 0,
295
+ }) as EnsureType<TInput, number>;
296
+ }
297
+
298
+ average(_throwOnNumberLimit?: boolean): EnsureType<TInput, number> {
299
+ return ((this.sum() as number) / this.size()) as EnsureType<
300
+ TInput,
301
+ number
302
+ >;
303
+ }
304
+
305
+ median(_throwOnNumberLimit?: boolean): EnsureType<TInput, number> {
306
+ try {
307
+ const nbrs = this.array.map((item) => {
308
+ if (typeof item !== "number") {
309
+ throw new TypeError(
310
+ "Item type is invalid must be number",
311
+ );
312
+ }
313
+ return item;
314
+ }),
315
+ index = Math.floor(this.array.length / 2),
316
+ isEven = this.array.length % 2 === 0,
317
+ a = nbrs[index];
318
+ if (a === undefined) {
319
+ throw new UnexpectedCollectionError("Is in invalid state");
320
+ }
321
+ const b = nbrs[index - 1];
322
+ if (isEven) {
323
+ if (b === undefined) {
324
+ throw new UnexpectedCollectionError("Is in invalid state");
325
+ }
326
+ return ((a + b) / 2) as EnsureType<TInput, number>;
327
+ }
328
+ return a as EnsureType<TInput, number>;
329
+ } catch (error: unknown) {
330
+ if (
331
+ error instanceof CollectionError ||
332
+ error instanceof TypeError
333
+ ) {
334
+ throw error;
335
+ }
336
+ throw new UnexpectedCollectionError(
337
+ `Unexpected error "${String(error)}" occured`,
338
+ error,
339
+ );
340
+ }
341
+ }
342
+
343
+ min(): EnsureType<TInput, number> {
344
+ try {
345
+ let min = 0;
346
+ for (const item of this.array) {
347
+ if (typeof item !== "number") {
348
+ throw new TypeError("Item type is invalid must be number");
349
+ }
350
+ if (min === 0) {
351
+ min = item;
352
+ } else if (min > item) {
353
+ min = item;
354
+ }
355
+ }
356
+ return min as EnsureType<TInput, number>;
357
+ } catch (error: unknown) {
358
+ if (
359
+ error instanceof CollectionError ||
360
+ error instanceof TypeError
361
+ ) {
362
+ throw error;
363
+ }
364
+ throw new UnexpectedCollectionError(
365
+ `Unexpected error "${String(error)}" occured`,
366
+ error,
367
+ );
368
+ }
369
+ }
370
+
371
+ max(): EnsureType<TInput, number> {
372
+ try {
373
+ let max = 0;
374
+ for (const item of this.array) {
375
+ if (typeof item !== "number") {
376
+ throw new TypeError("Item type is invalid must be number");
377
+ }
378
+ if (max === 0) {
379
+ max = item;
380
+ } else if (max < item) {
381
+ max = item;
382
+ }
383
+ }
384
+ return max as EnsureType<TInput, number>;
385
+ } catch (error: unknown) {
386
+ if (
387
+ error instanceof CollectionError ||
388
+ error instanceof TypeError
389
+ ) {
390
+ throw error;
391
+ }
392
+ throw new UnexpectedCollectionError(
393
+ `Unexpected error "${String(error)}" occured`,
394
+ error,
395
+ );
396
+ }
397
+ }
398
+
399
+ percentage(
400
+ filter: Filter<TInput, ICollection<TInput>>,
401
+ _throwOnNumberLimit?: boolean,
402
+ ): number {
403
+ try {
404
+ return (this.count(filter) / this.size()) * 100;
405
+ } catch (error: unknown) {
406
+ if (
407
+ error instanceof CollectionError ||
408
+ error instanceof TypeError
409
+ ) {
410
+ throw error;
411
+ }
412
+ throw new UnexpectedCollectionError(
413
+ `Unexpected error "${String(error)}" occured`,
414
+ error,
415
+ );
416
+ }
417
+ }
418
+
419
+ some<TOutput extends TInput>(
420
+ filter: Filter<TInput, ICollection<TInput>, TOutput>,
421
+ _throwOnNumberLimit?: boolean,
422
+ ): boolean {
423
+ try {
424
+ return this.array.some((item, index) => filter(item, index, this));
425
+ } catch (error: unknown) {
426
+ if (
427
+ error instanceof CollectionError ||
428
+ error instanceof TypeError
429
+ ) {
430
+ throw error;
431
+ }
432
+ throw new UnexpectedCollectionError(
433
+ `Unexpected error "${String(error)}" occured`,
434
+ error,
435
+ );
436
+ }
437
+ }
438
+
439
+ every<TOutput extends TInput>(
440
+ filter: Filter<TInput, ICollection<TInput>, TOutput>,
441
+ _throwOnNumberLimit?: boolean,
442
+ ): boolean {
443
+ try {
444
+ return this.array.every((item, index) => filter(item, index, this));
445
+ } catch (error: unknown) {
446
+ if (
447
+ error instanceof CollectionError ||
448
+ error instanceof TypeError
449
+ ) {
450
+ throw error;
451
+ }
452
+ throw new UnexpectedCollectionError(
453
+ `Unexpected error "${String(error)}" occured`,
454
+ error,
455
+ );
456
+ }
457
+ }
458
+
459
+ take(limit: number, _throwOnNumberLimit?: boolean): ICollection<TInput> {
460
+ try {
461
+ return new ListCollection(this.array.slice(0, limit));
462
+ } catch (error: unknown) {
463
+ if (
464
+ error instanceof CollectionError ||
465
+ error instanceof TypeError
466
+ ) {
467
+ throw error;
468
+ }
469
+ throw new UnexpectedCollectionError(
470
+ `Unexpected error "${String(error)}" occured`,
471
+ error,
472
+ );
473
+ }
474
+ }
475
+
476
+ takeUntil(
477
+ filter: Filter<TInput, ICollection<TInput>>,
478
+ _throwOnNumberLimit?: boolean,
479
+ ): ICollection<TInput> {
480
+ try {
481
+ const items: TInput[] = [];
482
+ for (const [index, item] of this.array.entries()) {
483
+ if (filter(item, index, this)) {
484
+ break;
485
+ }
486
+ items.push(item);
487
+ }
488
+ return new ListCollection(items);
489
+ } catch (error: unknown) {
490
+ if (
491
+ error instanceof CollectionError ||
492
+ error instanceof TypeError
493
+ ) {
494
+ throw error;
495
+ }
496
+ throw new UnexpectedCollectionError(
497
+ `Unexpected error "${String(error)}" occured`,
498
+ error,
499
+ );
500
+ }
501
+ }
502
+
503
+ takeWhile(
504
+ filter: Filter<TInput, ICollection<TInput>>,
505
+ _throwOnNumberLimit?: boolean,
506
+ ): ICollection<TInput> {
507
+ try {
508
+ return this.takeUntil((...arguments_) => !filter(...arguments_));
509
+ } catch (error: unknown) {
510
+ if (
511
+ error instanceof CollectionError ||
512
+ error instanceof TypeError
513
+ ) {
514
+ throw error;
515
+ }
516
+ throw new UnexpectedCollectionError(
517
+ `Unexpected error "${String(error)}" occured`,
518
+ error,
519
+ );
520
+ }
521
+ }
522
+
523
+ skip(offset: number, _throwOnNumberLimit?: boolean): ICollection<TInput> {
524
+ try {
525
+ return new ListCollection(this.array.slice(offset));
526
+ } catch (error: unknown) {
527
+ if (
528
+ error instanceof CollectionError ||
529
+ error instanceof TypeError
530
+ ) {
531
+ throw error;
532
+ }
533
+ throw new UnexpectedCollectionError(
534
+ `Unexpected error "${String(error)}" occured`,
535
+ error,
536
+ );
537
+ }
538
+ }
539
+
540
+ skipUntil(
541
+ filter: Filter<TInput, ICollection<TInput>>,
542
+ _throwOnNumberLimit?: boolean,
543
+ ): ICollection<TInput> {
544
+ try {
545
+ let hasMatched = false;
546
+ const items: TInput[] = [];
547
+ for (const [index, item] of this.array.entries()) {
548
+ if (!hasMatched) {
549
+ hasMatched = filter(item, index, this);
550
+ }
551
+ if (hasMatched) {
552
+ items.push(item);
553
+ }
554
+ }
555
+ return new ListCollection(items);
556
+ } catch (error: unknown) {
557
+ if (
558
+ error instanceof CollectionError ||
559
+ error instanceof TypeError
560
+ ) {
561
+ throw error;
562
+ }
563
+ throw new UnexpectedCollectionError(
564
+ `Unexpected error "${String(error)}" occured`,
565
+ error,
566
+ );
567
+ }
568
+ }
569
+
570
+ skipWhile(
571
+ filter: Filter<TInput, ICollection<TInput>>,
572
+ _throwOnNumberLimit?: boolean,
573
+ ): ICollection<TInput> {
574
+ try {
575
+ return this.skipUntil((...arguments_) => !filter(...arguments_));
576
+ } catch (error: unknown) {
577
+ if (
578
+ error instanceof CollectionError ||
579
+ error instanceof TypeError
580
+ ) {
581
+ throw error;
582
+ }
583
+ throw new UnexpectedCollectionError(
584
+ `Unexpected error "${String(error)}" occured`,
585
+ error,
586
+ );
587
+ }
588
+ }
589
+
590
+ when<TExtended = TInput>(
591
+ condition: boolean,
592
+ callback: Modifier<ICollection<TInput>, ICollection<TExtended>>,
593
+ ): ICollection<TInput | TExtended> {
594
+ try {
595
+ if (condition) {
596
+ return callback(this);
597
+ }
598
+ return this as ICollection<TInput | TExtended>;
599
+ } catch (error: unknown) {
600
+ if (
601
+ error instanceof CollectionError ||
602
+ error instanceof TypeError
603
+ ) {
604
+ throw error;
605
+ }
606
+ throw new UnexpectedCollectionError(
607
+ `Unexpected error "${String(error)}" occured`,
608
+ error,
609
+ );
610
+ }
611
+ }
612
+
613
+ whenEmpty<TExtended = TInput>(
614
+ callback: Modifier<ICollection<TInput>, ICollection<TExtended>>,
615
+ ): ICollection<TInput | TExtended> {
616
+ try {
617
+ return this.when(this.empty(), callback);
618
+ } catch (error: unknown) {
619
+ if (
620
+ error instanceof CollectionError ||
621
+ error instanceof TypeError
622
+ ) {
623
+ throw error;
624
+ }
625
+ throw new UnexpectedCollectionError(
626
+ `Unexpected error "${String(error)}" occured`,
627
+ error,
628
+ );
629
+ }
630
+ }
631
+
632
+ whenNot<TExtended = TInput>(
633
+ condition: boolean,
634
+ callback: Modifier<ICollection<TInput>, ICollection<TExtended>>,
635
+ ): ICollection<TInput | TExtended> {
636
+ try {
637
+ return this.when(!condition, callback);
638
+ } catch (error: unknown) {
639
+ if (
640
+ error instanceof CollectionError ||
641
+ error instanceof TypeError
642
+ ) {
643
+ throw error;
644
+ }
645
+ throw new UnexpectedCollectionError(
646
+ `Unexpected error "${String(error)}" occured`,
647
+ error,
648
+ );
649
+ }
650
+ }
651
+
652
+ whenNotEmpty<TExtended = TInput>(
653
+ callback: Modifier<ICollection<TInput>, ICollection<TExtended>>,
654
+ ): ICollection<TInput | TExtended> {
655
+ try {
656
+ return this.when(this.notEmpty(), callback);
657
+ } catch (error: unknown) {
658
+ if (
659
+ error instanceof CollectionError ||
660
+ error instanceof TypeError
661
+ ) {
662
+ throw error;
663
+ }
664
+ throw new UnexpectedCollectionError(
665
+ `Unexpected error "${String(error)}" occured`,
666
+ error,
667
+ );
668
+ }
669
+ }
670
+
671
+ pipe<TOutput = TInput>(
672
+ callback: Transform<ICollection<TInput>, TOutput>,
673
+ ): TOutput {
674
+ try {
675
+ return callback(this);
676
+ } catch (error: unknown) {
677
+ if (
678
+ error instanceof CollectionError ||
679
+ error instanceof TypeError
680
+ ) {
681
+ throw error;
682
+ }
683
+ throw new UnexpectedCollectionError(
684
+ `Unexpected error "${String(error)}" occured`,
685
+ error,
686
+ );
687
+ }
688
+ }
689
+
690
+ tap(callback: Tap<ICollection<TInput>>): ICollection<TInput> {
691
+ try {
692
+ callback(this);
693
+ return new ListCollection(this);
694
+ } catch (error: unknown) {
695
+ if (
696
+ error instanceof CollectionError ||
697
+ error instanceof TypeError
698
+ ) {
699
+ throw error;
700
+ }
701
+ throw new UnexpectedCollectionError(
702
+ `Unexpected error "${String(error)}" occured`,
703
+ error,
704
+ );
705
+ }
706
+ }
707
+
708
+ chunk(chunkSize: number): ICollection<ICollection<TInput>> {
709
+ try {
710
+ const chunks: ICollection<TInput>[] = [];
711
+ for (let index = 0; index < this.size(); index += chunkSize) {
712
+ chunks.push(
713
+ new ListCollection(
714
+ this.array.slice(index, index + chunkSize),
715
+ ),
716
+ );
717
+ }
718
+ return new ListCollection(chunks);
719
+ } catch (error: unknown) {
720
+ if (
721
+ error instanceof CollectionError ||
722
+ error instanceof TypeError
723
+ ) {
724
+ throw error;
725
+ }
726
+ throw new UnexpectedCollectionError(
727
+ `Unexpected error "${String(error)}" occured`,
728
+ error,
729
+ );
730
+ }
731
+ }
732
+
733
+ chunkWhile(
734
+ filter: Filter<TInput, ICollection<TInput>>,
735
+ _throwOnNumberLimit?: boolean,
736
+ ): ICollection<ICollection<TInput>> {
737
+ try {
738
+ let currentChunk: ICollection<TInput> = new ListCollection<TInput>(
739
+ [],
740
+ );
741
+ const chunks: ICollection<TInput>[] = [];
742
+ for (const [index, item] of this.array.entries()) {
743
+ if (index === 0) {
744
+ currentChunk = currentChunk.append([item]);
745
+ } else if (filter(item, index, currentChunk)) {
746
+ currentChunk = currentChunk.append([item]);
747
+ } else {
748
+ chunks.push(currentChunk);
749
+ currentChunk = new ListCollection<TInput>([item]);
750
+ }
751
+ }
752
+ chunks.push(currentChunk);
753
+ return new ListCollection(chunks);
754
+ } catch (error: unknown) {
755
+ if (
756
+ error instanceof CollectionError ||
757
+ error instanceof TypeError
758
+ ) {
759
+ throw error;
760
+ }
761
+ throw new UnexpectedCollectionError(
762
+ `Unexpected error "${String(error)}" occured`,
763
+ error,
764
+ );
765
+ }
766
+ }
767
+
768
+ split(
769
+ chunkAmount: number,
770
+ _throwOnNumberLimit?: boolean,
771
+ ): ICollection<ICollection<TInput>> {
772
+ try {
773
+ const size = this.size(),
774
+ minChunkSize = Math.floor(size / chunkAmount),
775
+ restSize = size % chunkAmount,
776
+ chunkSizes = Array.from<number>({
777
+ length: chunkAmount,
778
+ }).fill(minChunkSize);
779
+
780
+ for (let index = 1; index <= restSize; index++) {
781
+ const chunkIndex = (index - 1) % chunkAmount;
782
+ if (chunkSizes[chunkIndex]) {
783
+ chunkSizes[chunkIndex] = chunkSizes[chunkIndex] + 1;
784
+ }
785
+ }
786
+
787
+ let end = 0,
788
+ start = 0;
789
+ const chunks: ICollection<TInput>[] = [];
790
+ for (const chunkSize of chunkSizes) {
791
+ end += chunkSize;
792
+ chunks.push(new ListCollection(this.array.slice(start, end)));
793
+ start += chunkSize;
794
+ }
795
+
796
+ return new ListCollection<ICollection<TInput>>(chunks);
797
+ } catch (error: unknown) {
798
+ if (
799
+ error instanceof CollectionError ||
800
+ error instanceof TypeError
801
+ ) {
802
+ throw error;
803
+ }
804
+ throw new UnexpectedCollectionError(
805
+ `Unexpected error "${String(error)}" occured`,
806
+ error,
807
+ );
808
+ }
809
+ }
810
+
811
+ partition(
812
+ filter: Filter<TInput, ICollection<TInput>>,
813
+ _throwOnNumberLimit?: boolean,
814
+ ): ICollection<ICollection<TInput>> {
815
+ try {
816
+ const chunkA: TInput[] = [],
817
+ chunkB: TInput[] = [];
818
+ for (const [index, item] of this.array.entries()) {
819
+ if (filter(item, index, this)) {
820
+ chunkA.push(item);
821
+ } else {
822
+ chunkB.push(item);
823
+ }
824
+ }
825
+ return new ListCollection<ICollection<TInput>>([
826
+ new ListCollection(chunkA),
827
+ new ListCollection(chunkB),
828
+ ]);
829
+ } catch (error: unknown) {
830
+ if (
831
+ error instanceof CollectionError ||
832
+ error instanceof TypeError
833
+ ) {
834
+ throw error;
835
+ }
836
+ throw new UnexpectedCollectionError(
837
+ `Unexpected error "${String(error)}" occured`,
838
+ error,
839
+ );
840
+ }
841
+ }
842
+
843
+ sliding(settings: SlidingSettings): ICollection<ICollection<TInput>> {
844
+ try {
845
+ const { chunkSize, step = chunkSize - 1 } = settings;
846
+ let chunks: ICollection<ICollection<TInput>> = new ListCollection<
847
+ ICollection<TInput>
848
+ >([]);
849
+ if (step <= 0) {
850
+ return new ListCollection<ICollection<TInput>>([]);
851
+ }
852
+ for (let index = 0; index < this.size(); index += step) {
853
+ const start = index;
854
+ const end = index + chunkSize;
855
+ chunks = chunks.append([
856
+ this.slice({
857
+ start,
858
+ end,
859
+ }),
860
+ ]);
861
+ if (end >= this.size()) {
862
+ break;
863
+ }
864
+ }
865
+ return chunks;
866
+ } catch (error: unknown) {
867
+ if (
868
+ error instanceof CollectionError ||
869
+ error instanceof TypeError
870
+ ) {
871
+ throw error;
872
+ }
873
+ throw new UnexpectedCollectionError(
874
+ `Unexpected error "${String(error)}" occured`,
875
+ error,
876
+ );
877
+ }
878
+ }
879
+
880
+ groupBy<TOutput = TInput>(
881
+ settings?: GroupBySettings<TInput, ICollection<TInput>, TOutput>,
882
+ ): ICollection<RecordItem<TOutput, ICollection<TInput>>> {
883
+ try {
884
+ const map = new Map<TOutput, ICollection<TInput>>(),
885
+ callback = (settings?.mapFn ?? ((item) => item)) as Map<
886
+ TInput,
887
+ ICollection<TInput>,
888
+ TOutput
889
+ >;
890
+ for (const [index, item] of this.array.entries()) {
891
+ const key = callback(item, index, this);
892
+ let collection: ICollection<TInput> | undefined = map.get(key);
893
+ if (collection === undefined) {
894
+ collection = new ListCollection<TInput>([]);
895
+ map.set(key, collection);
896
+ }
897
+
898
+ map.set(key, collection.append([item]));
899
+ }
900
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
901
+ return new ListCollection(map as any);
902
+ } catch (error: unknown) {
903
+ if (
904
+ error instanceof CollectionError ||
905
+ error instanceof TypeError
906
+ ) {
907
+ throw error;
908
+ }
909
+ throw new UnexpectedCollectionError(
910
+ `Unexpected error "${String(error)}" occured`,
911
+ error,
912
+ );
913
+ }
914
+ }
915
+
916
+ countBy<TOutput = TInput>(
917
+ settings?: GroupBySettings<TInput, ICollection<TInput>, TOutput>,
918
+ ): ICollection<RecordItem<TOutput, number>> {
919
+ try {
920
+ const map = new Map<TOutput, number>(),
921
+ callback = (settings?.mapFn ?? ((item) => item)) as Map<
922
+ TInput,
923
+ ICollection<TInput>,
924
+ TOutput
925
+ >;
926
+ for (const [index, item] of this.array.entries()) {
927
+ const key = callback(item, index, this);
928
+ if (!map.has(key)) {
929
+ map.set(key, 0);
930
+ }
931
+ const counter = map.get(key);
932
+ if (counter !== undefined) {
933
+ map.set(key, counter + 1);
934
+ }
935
+ }
936
+ return new ListCollection(map);
937
+ } catch (error: unknown) {
938
+ if (
939
+ error instanceof CollectionError ||
940
+ error instanceof TypeError
941
+ ) {
942
+ throw error;
943
+ }
944
+ throw new UnexpectedCollectionError(
945
+ `Unexpected error "${String(error)}" occured`,
946
+ error,
947
+ );
948
+ }
949
+ }
950
+
951
+ unique<TOutput = TInput>(
952
+ settings?: GroupBySettings<TInput, ICollection<TInput>, TOutput>,
953
+ ): ICollection<TInput> {
954
+ try {
955
+ const set = new Set<TOutput>([]),
956
+ callback = (settings?.mapFn ?? ((item) => item)) as Map<
957
+ TInput,
958
+ ICollection<TInput>,
959
+ TOutput
960
+ >,
961
+ items: TInput[] = [];
962
+ for (const [index, item] of this.array.entries()) {
963
+ const item_ = callback(item, index, this);
964
+ if (!set.has(item_)) {
965
+ items.push(item);
966
+ }
967
+ set.add(item_);
968
+ }
969
+ return new ListCollection(items);
970
+ } catch (error: unknown) {
971
+ if (
972
+ error instanceof CollectionError ||
973
+ error instanceof TypeError
974
+ ) {
975
+ throw error;
976
+ }
977
+ throw new UnexpectedCollectionError(
978
+ `Unexpected error "${String(error)}" occured`,
979
+ error,
980
+ );
981
+ }
982
+ }
983
+
984
+ difference<TOutput = TInput>(
985
+ iterable: Iterable<TInput>,
986
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any
987
+ map: Map<TInput, ICollection<TInput>, TOutput> = (item) => item as any,
988
+ ): ICollection<TInput> {
989
+ try {
990
+ const differenceCollection = new ListCollection(iterable);
991
+ return this.filter((item, index, collection) => {
992
+ return !differenceCollection.some(
993
+ (matchItem, matchIndex, matchCollection) => {
994
+ return (
995
+ map(item, index, collection) ===
996
+ map(matchItem, matchIndex, matchCollection)
997
+ );
998
+ },
999
+ );
1000
+ });
1001
+ } catch (error: unknown) {
1002
+ if (
1003
+ error instanceof CollectionError ||
1004
+ error instanceof TypeError
1005
+ ) {
1006
+ throw error;
1007
+ }
1008
+ throw new UnexpectedCollectionError(
1009
+ `Unexpected error "${String(error)}" occured`,
1010
+ error,
1011
+ );
1012
+ }
1013
+ }
1014
+
1015
+ repeat(amount: number): ICollection<TInput> {
1016
+ try {
1017
+ let collection: ICollection<TInput> = new ListCollection<TInput>(
1018
+ [],
1019
+ );
1020
+ for (let index = 0; index < amount - 1; index++) {
1021
+ collection = collection.append(this);
1022
+ }
1023
+ return collection;
1024
+ } catch (error: unknown) {
1025
+ if (
1026
+ error instanceof CollectionError ||
1027
+ error instanceof TypeError
1028
+ ) {
1029
+ throw error;
1030
+ }
1031
+ throw new UnexpectedCollectionError(
1032
+ `Unexpected error "${String(error)}" occured`,
1033
+ error,
1034
+ );
1035
+ }
1036
+ }
1037
+
1038
+ padStart<TExtended = TInput>(
1039
+ maxLength: number,
1040
+ fillItems: Iterable<TExtended>,
1041
+ ): ICollection<TInput | TExtended> {
1042
+ try {
1043
+ const fillItemsArray = [...fillItems];
1044
+ const size = this.size();
1045
+ const repeat = Math.floor(
1046
+ (maxLength - size) / fillItemsArray.length,
1047
+ );
1048
+ const resultItemsArray: Array<TInput | TExtended> = [];
1049
+ for (let index = 0; index < repeat; index++) {
1050
+ resultItemsArray.push(...fillItemsArray);
1051
+ }
1052
+ const restAmount =
1053
+ maxLength - (repeat * fillItemsArray.length + size);
1054
+ for (let index = 0; index < restAmount; index++) {
1055
+ const fillItem = fillItemsArray[index];
1056
+ if (fillItem) {
1057
+ resultItemsArray.push(fillItem);
1058
+ }
1059
+ }
1060
+ resultItemsArray.push(...this);
1061
+ return new ListCollection<TInput | TExtended>(resultItemsArray);
1062
+ } catch (error: unknown) {
1063
+ if (
1064
+ error instanceof CollectionError ||
1065
+ error instanceof TypeError
1066
+ ) {
1067
+ throw error;
1068
+ }
1069
+ throw new UnexpectedCollectionError(
1070
+ `Unexpected error "${String(error)}" occured`,
1071
+ error,
1072
+ );
1073
+ }
1074
+ }
1075
+
1076
+ padEnd<TExtended = TInput>(
1077
+ maxLength: number,
1078
+ fillItems: Iterable<TExtended>,
1079
+ ): ICollection<TInput | TExtended> {
1080
+ try {
1081
+ const fillItemsArray = [...fillItems];
1082
+ const size = this.size();
1083
+ const repeat = Math.floor(
1084
+ (maxLength - size) / fillItemsArray.length,
1085
+ );
1086
+ const resultItemsArray: Array<TInput | TExtended> = [];
1087
+ for (let index = 0; index < repeat; index++) {
1088
+ resultItemsArray.push(...fillItemsArray);
1089
+ }
1090
+ const restAmount =
1091
+ maxLength - (repeat * fillItemsArray.length + size);
1092
+ for (let index = 0; index < restAmount; index++) {
1093
+ const fillItem = fillItemsArray[index];
1094
+ if (fillItem) {
1095
+ resultItemsArray.push(fillItem);
1096
+ }
1097
+ }
1098
+ resultItemsArray.unshift(...this);
1099
+ return new ListCollection<TInput | TExtended>(resultItemsArray);
1100
+ } catch (error: unknown) {
1101
+ if (
1102
+ error instanceof CollectionError ||
1103
+ error instanceof TypeError
1104
+ ) {
1105
+ throw error;
1106
+ }
1107
+ throw new UnexpectedCollectionError(
1108
+ `Unexpected error "${String(error)}" occured`,
1109
+ error,
1110
+ );
1111
+ }
1112
+ }
1113
+
1114
+ slice(settings?: SliceSettings): ICollection<TInput> {
1115
+ try {
1116
+ return new ListCollection(
1117
+ this.array.slice(settings?.start, settings?.end),
1118
+ );
1119
+ } catch (error: unknown) {
1120
+ if (
1121
+ error instanceof CollectionError ||
1122
+ error instanceof TypeError
1123
+ ) {
1124
+ throw error;
1125
+ }
1126
+ throw new UnexpectedCollectionError(
1127
+ `Unexpected error "${String(error)}" occured`,
1128
+ error,
1129
+ );
1130
+ }
1131
+ }
1132
+
1133
+ prepend<TExtended = TInput>(
1134
+ iterable: Iterable<TInput | TExtended>,
1135
+ ): ICollection<TInput | TExtended> {
1136
+ try {
1137
+ return new ListCollection([...iterable, ...this.array]);
1138
+ } catch (error: unknown) {
1139
+ if (
1140
+ error instanceof CollectionError ||
1141
+ error instanceof TypeError
1142
+ ) {
1143
+ throw error;
1144
+ }
1145
+ throw new UnexpectedCollectionError(
1146
+ `Unexpected error "${String(error)}" occured`,
1147
+ error,
1148
+ );
1149
+ }
1150
+ }
1151
+
1152
+ append<TExtended = TInput>(
1153
+ iterable: Iterable<TInput | TExtended>,
1154
+ ): ICollection<TInput | TExtended> {
1155
+ try {
1156
+ return new ListCollection([...this.array, ...iterable]);
1157
+ } catch (error: unknown) {
1158
+ if (
1159
+ error instanceof CollectionError ||
1160
+ error instanceof TypeError
1161
+ ) {
1162
+ throw error;
1163
+ }
1164
+ throw new UnexpectedCollectionError(
1165
+ `Unexpected error "${String(error)}" occured`,
1166
+ error,
1167
+ );
1168
+ }
1169
+ }
1170
+
1171
+ insertBefore<TExtended = TInput>(
1172
+ filter: Filter<TInput, ICollection<TInput>>,
1173
+ iterable: Iterable<TInput | TExtended>,
1174
+ _throwOnNumberLimit?: boolean,
1175
+ ): ICollection<TInput | TExtended> {
1176
+ try {
1177
+ const index = this.array.findIndex((item, index) =>
1178
+ filter(item, index, this),
1179
+ );
1180
+ if (index === -1) {
1181
+ return new ListCollection<TInput | TExtended>(this.array);
1182
+ }
1183
+ const newArray = [...this.array] as Array<TInput | TExtended>;
1184
+ newArray.splice(index, 0, ...iterable);
1185
+ return new ListCollection(newArray);
1186
+ } catch (error: unknown) {
1187
+ if (
1188
+ error instanceof CollectionError ||
1189
+ error instanceof TypeError
1190
+ ) {
1191
+ throw error;
1192
+ }
1193
+ throw new UnexpectedCollectionError(
1194
+ `Unexpected error "${String(error)}" occured`,
1195
+ error,
1196
+ );
1197
+ }
1198
+ }
1199
+
1200
+ insertAfter<TExtended = TInput>(
1201
+ filter: Filter<TInput, ICollection<TInput>>,
1202
+ iterable: Iterable<TInput | TExtended>,
1203
+ _throwOnNumberLimit?: boolean,
1204
+ ): ICollection<TInput | TExtended> {
1205
+ try {
1206
+ const index = this.array.findIndex((item, index) =>
1207
+ filter(item, index, this),
1208
+ );
1209
+ if (index === -1) {
1210
+ return new ListCollection(this.array) as ICollection<
1211
+ TInput | TExtended
1212
+ >;
1213
+ }
1214
+ const firstPart = this.array.slice(0, index + 1),
1215
+ lastPart = this.array.slice(index + 1);
1216
+ return new ListCollection([
1217
+ ...firstPart,
1218
+ ...iterable,
1219
+ ...lastPart,
1220
+ ]) as ICollection<TInput | TExtended>;
1221
+ } catch (error: unknown) {
1222
+ if (
1223
+ error instanceof CollectionError ||
1224
+ error instanceof TypeError
1225
+ ) {
1226
+ throw error;
1227
+ }
1228
+ throw new UnexpectedCollectionError(
1229
+ `Unexpected error "${String(error)}" occured`,
1230
+ error,
1231
+ );
1232
+ }
1233
+ }
1234
+
1235
+ crossJoin<TExtended = TInput>(
1236
+ ...iterables: Array<Iterable<TExtended>>
1237
+ ): ICollection<ICollection<TInput | TExtended>> {
1238
+ try {
1239
+ return new ListCollection<ICollection<TInput | TExtended>>([
1240
+ this as ICollection<TInput>,
1241
+ ...iterables.map<ICollection<TExtended>>(
1242
+ (iterable) => new ListCollection(iterable),
1243
+ ),
1244
+ ]).reduce<ICollection<ICollection<TInput | TExtended>>>({
1245
+ reduceFn: (a, b) => {
1246
+ return a
1247
+ .map((x) =>
1248
+ b.map((y) => {
1249
+ return x.append([y]);
1250
+ }),
1251
+ )
1252
+ .reduce<ICollection<ICollection<TInput | TExtended>>>({
1253
+ reduceFn: (c, b) => c.append(b),
1254
+ initialValue: new ListCollection<
1255
+ ICollection<TInput | TExtended>
1256
+ >([]),
1257
+ });
1258
+ },
1259
+ initialValue: new ListCollection<
1260
+ ICollection<TInput | TExtended>
1261
+ >([new ListCollection<TInput | TExtended>([])]),
1262
+ });
1263
+ } catch (error: unknown) {
1264
+ if (
1265
+ error instanceof CollectionError ||
1266
+ error instanceof TypeError
1267
+ ) {
1268
+ throw error;
1269
+ }
1270
+ throw new UnexpectedCollectionError(
1271
+ `Unexpected error "${String(error)}" occured`,
1272
+ error,
1273
+ );
1274
+ }
1275
+ }
1276
+
1277
+ zip<TExtended>(
1278
+ iterable: Iterable<TExtended>,
1279
+ ): ICollection<RecordItem<TInput, TExtended>> {
1280
+ try {
1281
+ const iterableArray = [...iterable];
1282
+ let size = iterableArray.length;
1283
+ if (size > this.size()) {
1284
+ size = this.size();
1285
+ }
1286
+ const items: RecordItem<TInput, TExtended>[] = [];
1287
+ for (let index = 0; index < size; index++) {
1288
+ const itemA = this.array[index],
1289
+ itemB = iterableArray[index];
1290
+ if (itemA === undefined || itemB === undefined) {
1291
+ continue;
1292
+ }
1293
+ items.push([itemA, itemB]);
1294
+ }
1295
+ return new ListCollection(items);
1296
+ } catch (error: unknown) {
1297
+ if (
1298
+ error instanceof CollectionError ||
1299
+ error instanceof TypeError
1300
+ ) {
1301
+ throw error;
1302
+ }
1303
+ throw new UnexpectedCollectionError(
1304
+ `Unexpected error "${String(error)}" occured`,
1305
+ error,
1306
+ );
1307
+ }
1308
+ }
1309
+
1310
+ sort(compare?: Comparator<TInput>): ICollection<TInput> {
1311
+ try {
1312
+ return new ListCollection(this.array.sort(compare));
1313
+ } catch (error: unknown) {
1314
+ if (
1315
+ error instanceof CollectionError ||
1316
+ error instanceof TypeError
1317
+ ) {
1318
+ throw error;
1319
+ }
1320
+ throw new UnexpectedCollectionError(
1321
+ `Unexpected error "${String(error)}" occured`,
1322
+ error,
1323
+ );
1324
+ }
1325
+ }
1326
+
1327
+ reverse(_settings?: ReverseSettings): ICollection<TInput> {
1328
+ try {
1329
+ return new ListCollection([...this.array].reverse());
1330
+ } catch (error: unknown) {
1331
+ if (
1332
+ error instanceof CollectionError ||
1333
+ error instanceof TypeError
1334
+ ) {
1335
+ throw error;
1336
+ }
1337
+ throw new UnexpectedCollectionError(
1338
+ `Unexpected error "${String(error)}" occured`,
1339
+ error,
1340
+ );
1341
+ }
1342
+ }
1343
+
1344
+ shuffle(): ICollection<TInput> {
1345
+ try {
1346
+ const newArray = [...this.array];
1347
+ for (let i = newArray.length - 1; i > 0; i--) {
1348
+ const j = Math.floor(Math.random() * (i + 1));
1349
+ const temp = newArray[i];
1350
+ if (newArray[j] !== undefined) {
1351
+ newArray[i] = newArray[j];
1352
+ }
1353
+ if (temp !== undefined) {
1354
+ newArray[j] = temp;
1355
+ }
1356
+ }
1357
+ return new ListCollection(newArray);
1358
+ } catch (error: unknown) {
1359
+ if (
1360
+ error instanceof CollectionError ||
1361
+ error instanceof TypeError
1362
+ ) {
1363
+ throw error;
1364
+ }
1365
+ throw new UnexpectedCollectionError(
1366
+ `Unexpected error "${String(error)}" occured`,
1367
+ error,
1368
+ );
1369
+ }
1370
+ }
1371
+
1372
+ first<TOutput extends TInput>(
1373
+ settings?: FindSettings<TInput, ICollection<TInput>, TOutput>,
1374
+ ): TOutput | null {
1375
+ try {
1376
+ return this.firstOr({
1377
+ defaultValue: null,
1378
+ ...settings,
1379
+ });
1380
+ } catch (error: unknown) {
1381
+ if (
1382
+ error instanceof CollectionError ||
1383
+ error instanceof TypeError
1384
+ ) {
1385
+ throw error;
1386
+ }
1387
+ throw new UnexpectedCollectionError(
1388
+ `Unexpected error "${String(error)}" occured`,
1389
+ error,
1390
+ );
1391
+ }
1392
+ }
1393
+
1394
+ firstOr<TOutput extends TInput, TExtended = TInput>(
1395
+ settings: FindOrSettings<
1396
+ TInput,
1397
+ ICollection<TInput>,
1398
+ TOutput,
1399
+ TExtended
1400
+ >,
1401
+ ): TOutput | TExtended {
1402
+ try {
1403
+ const { filterFn: filter } = settings;
1404
+ if (filter) {
1405
+ for (const [index, item] of this.array.entries()) {
1406
+ if (filter(item, index, this)) {
1407
+ return item as TOutput;
1408
+ }
1409
+ }
1410
+ } else {
1411
+ const firstItem = this.array[0];
1412
+ if (firstItem) {
1413
+ return firstItem as TOutput;
1414
+ }
1415
+ }
1416
+ const { defaultValue } = settings;
1417
+ if (typeof defaultValue === "function") {
1418
+ const defaultFn = defaultValue as () => TOutput;
1419
+ return defaultFn();
1420
+ }
1421
+ return defaultValue;
1422
+ } catch (error: unknown) {
1423
+ if (
1424
+ error instanceof CollectionError ||
1425
+ error instanceof TypeError
1426
+ ) {
1427
+ throw error;
1428
+ }
1429
+ throw new UnexpectedCollectionError(
1430
+ `Unexpected error "${String(error)}" occured`,
1431
+ error,
1432
+ );
1433
+ }
1434
+ }
1435
+
1436
+ firstOrFail<TOutput extends TInput>(
1437
+ settings?: FindSettings<TInput, ICollection<TInput>, TOutput>,
1438
+ ): TOutput {
1439
+ try {
1440
+ const item = this.first(settings);
1441
+ if (item === null) {
1442
+ throw new ItemNotFoundError("Item was not found");
1443
+ }
1444
+ return item;
1445
+ } catch (error: unknown) {
1446
+ if (
1447
+ error instanceof CollectionError ||
1448
+ error instanceof TypeError
1449
+ ) {
1450
+ throw error;
1451
+ }
1452
+ throw new UnexpectedCollectionError(
1453
+ `Unexpected error "${String(error)}" occured`,
1454
+ error,
1455
+ );
1456
+ }
1457
+ }
1458
+
1459
+ last<TOutput extends TInput>(
1460
+ settings?: FindSettings<TInput, ICollection<TInput>, TOutput>,
1461
+ ): TOutput | null {
1462
+ try {
1463
+ return this.lastOr({
1464
+ ...settings,
1465
+ defaultValue: null,
1466
+ });
1467
+ } catch (error: unknown) {
1468
+ if (
1469
+ error instanceof CollectionError ||
1470
+ error instanceof TypeError
1471
+ ) {
1472
+ throw error;
1473
+ }
1474
+ throw new UnexpectedCollectionError(
1475
+ `Unexpected error "${String(error)}" occured`,
1476
+ error,
1477
+ );
1478
+ }
1479
+ }
1480
+
1481
+ lastOr<TOutput extends TInput, TExtended = TInput>(
1482
+ settings: FindOrSettings<
1483
+ TInput,
1484
+ ICollection<TInput>,
1485
+ TOutput,
1486
+ TExtended
1487
+ >,
1488
+ ): TOutput | TExtended {
1489
+ try {
1490
+ const { filterFn: filter } = settings;
1491
+ if (filter) {
1492
+ let matchedItem: TOutput | null = null;
1493
+ for (const [index, item] of this.array.entries()) {
1494
+ if (filter(item, index, this)) {
1495
+ matchedItem = item as TOutput;
1496
+ }
1497
+ }
1498
+ if (matchedItem) {
1499
+ return matchedItem;
1500
+ }
1501
+ } else {
1502
+ const lastItem = this.array.at(-1);
1503
+ if (lastItem) {
1504
+ return lastItem as TOutput;
1505
+ }
1506
+ }
1507
+ const { defaultValue } = settings;
1508
+ if (typeof defaultValue === "function") {
1509
+ const defaultFn = defaultValue as () => TOutput;
1510
+ return defaultFn();
1511
+ }
1512
+ return defaultValue;
1513
+ } catch (error: unknown) {
1514
+ if (
1515
+ error instanceof CollectionError ||
1516
+ error instanceof TypeError
1517
+ ) {
1518
+ throw error;
1519
+ }
1520
+ throw new UnexpectedCollectionError(
1521
+ `Unexpected error "${String(error)}" occured`,
1522
+ error,
1523
+ );
1524
+ }
1525
+ }
1526
+
1527
+ lastOrFail<TOutput extends TInput>(
1528
+ settings?: FindSettings<TInput, ICollection<TInput>, TOutput>,
1529
+ ): TOutput {
1530
+ try {
1531
+ const item = this.last(settings);
1532
+ if (item === null) {
1533
+ throw new ItemNotFoundError("Item was not found");
1534
+ }
1535
+ return item;
1536
+ } catch (error: unknown) {
1537
+ if (
1538
+ error instanceof CollectionError ||
1539
+ error instanceof TypeError
1540
+ ) {
1541
+ throw error;
1542
+ }
1543
+ throw new UnexpectedCollectionError(
1544
+ `Unexpected error "${String(error)}" occured`,
1545
+ error,
1546
+ );
1547
+ }
1548
+ }
1549
+
1550
+ before(
1551
+ filter: Filter<TInput, ICollection<TInput>>,
1552
+ _throwOnNumberLimit?: boolean,
1553
+ ): TInput | null {
1554
+ try {
1555
+ return this.beforeOr(null, filter);
1556
+ } catch (error: unknown) {
1557
+ if (
1558
+ error instanceof CollectionError ||
1559
+ error instanceof TypeError
1560
+ ) {
1561
+ throw error;
1562
+ }
1563
+ throw new UnexpectedCollectionError(
1564
+ `Unexpected error "${String(error)}" occured`,
1565
+ error,
1566
+ );
1567
+ }
1568
+ }
1569
+
1570
+ beforeOr<TExtended = TInput>(
1571
+ defaultValue: Lazyable<TExtended>,
1572
+ filter: Filter<TInput, ICollection<TInput>>,
1573
+ _throwOnNumberLimit?: boolean,
1574
+ ): TInput | TExtended {
1575
+ try {
1576
+ for (const [index, item] of this.array.entries()) {
1577
+ const beforeItem = this.array[index - 1];
1578
+ if (filter(item, index, this) && beforeItem !== undefined) {
1579
+ return beforeItem;
1580
+ }
1581
+ }
1582
+ if (typeof defaultValue === "function") {
1583
+ const defaultFn = defaultValue as () => TExtended;
1584
+ return defaultFn();
1585
+ }
1586
+ return defaultValue;
1587
+ } catch (error: unknown) {
1588
+ if (
1589
+ error instanceof CollectionError ||
1590
+ error instanceof TypeError
1591
+ ) {
1592
+ throw error;
1593
+ }
1594
+ throw new UnexpectedCollectionError(
1595
+ `Unexpected error "${String(error)}" occured`,
1596
+ error,
1597
+ );
1598
+ }
1599
+ }
1600
+
1601
+ beforeOrFail(
1602
+ filter: Filter<TInput, ICollection<TInput>>,
1603
+ _throwOnNumberLimit?: boolean,
1604
+ ): TInput {
1605
+ try {
1606
+ const item = this.before(filter);
1607
+ if (item === null) {
1608
+ throw new ItemNotFoundError("Item was not found");
1609
+ }
1610
+ return item;
1611
+ } catch (error: unknown) {
1612
+ if (
1613
+ error instanceof CollectionError ||
1614
+ error instanceof TypeError
1615
+ ) {
1616
+ throw error;
1617
+ }
1618
+ throw new UnexpectedCollectionError(
1619
+ `Unexpected error "${String(error)}" occured`,
1620
+ error,
1621
+ );
1622
+ }
1623
+ }
1624
+
1625
+ after(
1626
+ filter: Filter<TInput, ICollection<TInput>>,
1627
+ _throwOnNumberLimit?: boolean,
1628
+ ): TInput | null {
1629
+ try {
1630
+ return this.afterOr(null, filter);
1631
+ } catch (error: unknown) {
1632
+ if (
1633
+ error instanceof CollectionError ||
1634
+ error instanceof TypeError
1635
+ ) {
1636
+ throw error;
1637
+ }
1638
+ throw new UnexpectedCollectionError(
1639
+ `Unexpected error "${String(error)}" occured`,
1640
+ error,
1641
+ );
1642
+ }
1643
+ }
1644
+
1645
+ afterOr<TExtended = TInput>(
1646
+ defaultValue: Lazyable<TExtended>,
1647
+ filter: Filter<TInput, ICollection<TInput>>,
1648
+ _throwOnNumberLimit?: boolean,
1649
+ ): TInput | TExtended {
1650
+ try {
1651
+ for (const [index, item] of this.array.entries()) {
1652
+ const beforeItem = this.array[index + 1];
1653
+ if (filter(item, index, this) && beforeItem !== undefined) {
1654
+ return beforeItem;
1655
+ }
1656
+ }
1657
+ if (typeof defaultValue === "function") {
1658
+ const defaultFn = defaultValue as () => TExtended;
1659
+ return defaultFn();
1660
+ }
1661
+ return defaultValue;
1662
+ } catch (error: unknown) {
1663
+ if (
1664
+ error instanceof CollectionError ||
1665
+ error instanceof TypeError
1666
+ ) {
1667
+ throw error;
1668
+ }
1669
+ throw new UnexpectedCollectionError(
1670
+ `Unexpected error "${String(error)}" occured`,
1671
+ error,
1672
+ );
1673
+ }
1674
+ }
1675
+
1676
+ afterOrFail(
1677
+ filter: Filter<TInput, ICollection<TInput>>,
1678
+ _throwOnNumberLimit?: boolean,
1679
+ ): TInput {
1680
+ try {
1681
+ const item = this.after(filter);
1682
+ if (item === null) {
1683
+ throw new ItemNotFoundError("Item was not found");
1684
+ }
1685
+ return item;
1686
+ } catch (error: unknown) {
1687
+ if (
1688
+ error instanceof CollectionError ||
1689
+ error instanceof TypeError
1690
+ ) {
1691
+ throw error;
1692
+ }
1693
+ throw new UnexpectedCollectionError(
1694
+ `Unexpected error "${String(error)}" occured`,
1695
+ error,
1696
+ );
1697
+ }
1698
+ }
1699
+
1700
+ sole<TOutput extends TInput>(
1701
+ filter: Filter<TInput, ICollection<TInput>, TOutput>,
1702
+ _throwOnNumberLimit?: boolean,
1703
+ ): TOutput {
1704
+ try {
1705
+ const matchedItems: TInput[] = [];
1706
+ for (const [index, item] of this.array.entries()) {
1707
+ if (filter(item, index, this)) {
1708
+ matchedItems.push(item);
1709
+ }
1710
+ if (matchedItems.length > 1) {
1711
+ throw new MultipleItemsFoundError(
1712
+ "Multiple items were found",
1713
+ );
1714
+ }
1715
+ }
1716
+ const [matchedItem] = matchedItems;
1717
+ if (matchedItem === undefined) {
1718
+ throw new ItemNotFoundError("Item was not found");
1719
+ }
1720
+ return matchedItem as TOutput;
1721
+ } catch (error: unknown) {
1722
+ if (
1723
+ error instanceof CollectionError ||
1724
+ error instanceof TypeError
1725
+ ) {
1726
+ throw error;
1727
+ }
1728
+ throw new UnexpectedCollectionError(
1729
+ `Unexpected error "${String(error)}" occured`,
1730
+ error,
1731
+ );
1732
+ }
1733
+ }
1734
+
1735
+ nth(step: number): ICollection<TInput> {
1736
+ try {
1737
+ return this.filter((_item, index) => index % step === 0);
1738
+ } catch (error: unknown) {
1739
+ if (
1740
+ error instanceof CollectionError ||
1741
+ error instanceof TypeError
1742
+ ) {
1743
+ throw error;
1744
+ }
1745
+ throw new UnexpectedCollectionError(
1746
+ `Unexpected error "${String(error)}" occured`,
1747
+ error,
1748
+ );
1749
+ }
1750
+ }
1751
+
1752
+ count(
1753
+ filter: Filter<TInput, ICollection<TInput>>,
1754
+ _throwOnNumberLimit?: boolean,
1755
+ ): number {
1756
+ try {
1757
+ return this.filter(filter).size();
1758
+ } catch (error: unknown) {
1759
+ if (
1760
+ error instanceof CollectionError ||
1761
+ error instanceof TypeError
1762
+ ) {
1763
+ throw error;
1764
+ }
1765
+ throw new UnexpectedCollectionError(
1766
+ `Unexpected error "${String(error)}" occured`,
1767
+ error,
1768
+ );
1769
+ }
1770
+ }
1771
+
1772
+ size(_throwOnNumberLimit?: boolean): number {
1773
+ try {
1774
+ return this.array.length;
1775
+ } catch (error: unknown) {
1776
+ if (
1777
+ error instanceof CollectionError ||
1778
+ error instanceof TypeError
1779
+ ) {
1780
+ throw error;
1781
+ }
1782
+ throw new UnexpectedCollectionError(
1783
+ `Unexpected error "${String(error)}" occured`,
1784
+ error,
1785
+ );
1786
+ }
1787
+ }
1788
+
1789
+ empty(): boolean {
1790
+ try {
1791
+ return this.array.length === 0;
1792
+ } catch (error: unknown) {
1793
+ if (
1794
+ error instanceof CollectionError ||
1795
+ error instanceof TypeError
1796
+ ) {
1797
+ throw error;
1798
+ }
1799
+ throw new UnexpectedCollectionError(
1800
+ `Unexpected error "${String(error)}" occured`,
1801
+ error,
1802
+ );
1803
+ }
1804
+ }
1805
+
1806
+ notEmpty(): boolean {
1807
+ try {
1808
+ return this.array.length !== 0;
1809
+ } catch (error: unknown) {
1810
+ if (
1811
+ error instanceof CollectionError ||
1812
+ error instanceof TypeError
1813
+ ) {
1814
+ throw error;
1815
+ }
1816
+ throw new UnexpectedCollectionError(
1817
+ `Unexpected error "${String(error)}" occured`,
1818
+ error,
1819
+ );
1820
+ }
1821
+ }
1822
+
1823
+ search(
1824
+ filter: Filter<TInput, ICollection<TInput>>,
1825
+ _throwOnNumberLimit?: boolean,
1826
+ ): number {
1827
+ try {
1828
+ return this.array.findIndex((item, index) =>
1829
+ filter(item, index, this),
1830
+ );
1831
+ } catch (error: unknown) {
1832
+ if (
1833
+ error instanceof CollectionError ||
1834
+ error instanceof TypeError
1835
+ ) {
1836
+ throw error;
1837
+ }
1838
+ throw new UnexpectedCollectionError(
1839
+ `Unexpected error "${String(error)}" occured`,
1840
+ error,
1841
+ );
1842
+ }
1843
+ }
1844
+
1845
+ forEach(
1846
+ callback: ForEach<TInput, ICollection<TInput>>,
1847
+ _throwOnNumberLimit?: boolean,
1848
+ ): void {
1849
+ try {
1850
+ for (const [index, item] of this.array.entries()) {
1851
+ callback(item, index, this);
1852
+ }
1853
+ } catch (error: unknown) {
1854
+ if (
1855
+ error instanceof CollectionError ||
1856
+ error instanceof TypeError
1857
+ ) {
1858
+ throw error;
1859
+ }
1860
+ throw new UnexpectedCollectionError(
1861
+ `Unexpected error "${String(error)}" occured`,
1862
+ error,
1863
+ );
1864
+ }
1865
+ }
1866
+
1867
+ toArray(): TInput[] {
1868
+ try {
1869
+ return [...this.array];
1870
+ } catch (error: unknown) {
1871
+ if (
1872
+ error instanceof CollectionError ||
1873
+ error instanceof TypeError
1874
+ ) {
1875
+ throw error;
1876
+ }
1877
+ throw new UnexpectedCollectionError(
1878
+ `Unexpected error "${String(error)}" occured`,
1879
+ error,
1880
+ );
1881
+ }
1882
+ }
1883
+ }