-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharray.ts
More file actions
344 lines (309 loc) · 6.97 KB
/
array.ts
File metadata and controls
344 lines (309 loc) · 6.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
/**
* @module
*
* Property list array.
*/
import type { PLType } from './type.ts';
const arrays = new WeakMap<PLArray, Array<PLType>>();
/**
* PLArray type.
*/
export const PLTYPE_ARRAY = 'PLArray' as const;
/**
* Property list array type.
*
* @template T Value type.
*/
export class PLArray<T extends PLType = PLType> {
declare public readonly [Symbol.toStringTag]: typeof PLTYPE_ARRAY;
/**
* Variable type.
*/
declare public readonly type: typeof PLTYPE_ARRAY;
/**
* Create property list array reference.
*
* @param entries Entries.
*/
constructor(entries: Iterable<T> | ArrayLike<T> | null = null) {
arrays.set(this, entries ? Array.from(entries) : []);
}
/**
* Get length.
*
* @returns Array length.
*/
public get length(): number {
return (arrays.get(this) as T[]).length;
}
/**
* Get value at index.
*
* @param index Array index.
* @returns Value at index or undefined.
*/
public get(index: number): T | undefined {
return (arrays.get(this) as T[])[(+index || 0) - (index % 1 || 0)];
}
/**
* Set value at index.
*
* @param index Array index.
* @param value Value to set.
*/
public set(index: number, value: T): void {
(arrays.get(this) as T[])[(+index || 0) - (index % 1 || 0)] = value;
}
/**
* Get value at index.
*
* @param index Array index, optionally negative.
* @returns Value at index or undefined.
*/
public at(index: number): T | undefined {
return (arrays.get(this) as T[]).at(index);
}
/**
* Push values to array.
*
* @param values Values to push.
* @returns New length.
*/
public push(...values: T[]): number {
return (arrays.get(this) as T[]).push(...values);
}
/**
* Pop value from array.
*
* @returns Popped value or undefined.
*/
public pop(): T | undefined {
return (arrays.get(this) as T[]).pop();
}
/**
* Unshift values to array.
*
* @param values Values to unshift.
* @returns New length.
*/
public unshift(...values: T[]): number {
return (arrays.get(this) as T[]).unshift(...values);
}
/**
* Shift value from array.
*
* @returns Shifted value or undefined.
*/
public shift(): T | undefined {
return (arrays.get(this) as T[]).shift();
}
/**
* Slice array.
*
* @param start Start index.
* @param end End index.
* @returns Sliced values.
*/
public slice(start?: number, end?: number): PLArray<T> {
return new PLArray((arrays.get(this) as T[]).slice(start, end));
}
/**
* Splice values from array.
*
* @param start Start index.
* @param deleteCount Delete count.
* @param items Values to insert.
* @returns Removed values.
*/
public splice(start: number, deleteCount = 0, ...items: T[]): T[] {
return (arrays.get(this) as T[]).splice(start, deleteCount, ...items);
}
/**
* Reverse array.
*/
public reverse(): void {
(arrays.get(this) as T[]).reverse();
}
/**
* Find index of value.
*
* @param value Value to find.
* @returns Index of value or -1.
*/
public indexOf(value: T): number {
return (arrays.get(this) as T[]).indexOf(value);
}
/**
* Find last index of value.
*
* @param value Value to find.
* @returns Last index of value or -1.
*/
public lastIndexOf(value: T): number {
return (arrays.get(this) as T[]).lastIndexOf(value);
}
/**
* Find value.
*
* @param callback Find callback.
* @param thisArg Callback context.
* @returns Found value or undefined.
*/
public find(
callback: (value: T, index: number, array: this) => boolean,
thisArg?: unknown,
): T | undefined {
return (arrays.get(this) as T[]).find(
(value, index) => callback.call(thisArg, value, index, this),
);
}
/**
* Find index of value.
*
* @param callback Find callback.
* @param thisArg Callback context.
* @returns Found index or -1.
*/
public findIndex(
callback: (value: T, index: number, array: this) => boolean,
thisArg?: unknown,
): number {
return (arrays.get(this) as T[]).findIndex((value, index) =>
callback.call(thisArg, value, index, this)
);
}
/**
* Find last value.
*
* @param callback Find callback.
* @param thisArg Callback context.
* @returns Found value or undefined.
*/
public findLast(
callback: (value: T, index: number, array: this) => boolean,
thisArg?: unknown,
): T | undefined {
return (arrays.get(this) as T[]).findLast((value, index) =>
callback.call(thisArg, value, index, this)
);
}
/**
* Find last index of value.
*
* @param callback Find callback.
* @param thisArg Callback context.
* @returns Found index or -1.
*/
public findLastIndex(
callback: (value: T, index: number, array: this) => boolean,
thisArg?: unknown,
): number {
return (arrays.get(this) as T[]).findLastIndex((value, index) =>
callback.call(thisArg, value, index, this)
);
}
/**
* Check if array includes value.
*
* @param value Value to check.
* @returns True if value is in array.
*/
public includes(value: T): boolean {
return (arrays.get(this) as T[]).includes(value);
}
/**
* Fill array with value.
*
* @param value Value to fill.
* @param start Start index.
* @param end End index.
*/
public fill(value: T, start?: number, end?: number): void {
(arrays.get(this) as T[]).fill(value, start, end);
}
/**
* Copy values within array.
*
* @param target Target index.
* @param start Start index.
* @param end End index.
*/
public copyWithin(target: number, start: number, end?: number): void {
(arrays.get(this) as T[]).copyWithin(target, start, end);
}
/**
* Clear array.
*/
public clear(): void {
(arrays.get(this) as T[]).length = 0;
}
/**
* Get array entries.
*
* @returns Array entries.
*/
public entries(): ArrayIterator<[number, T]> {
return (arrays.get(this) as T[]).entries();
}
/**
* Get array keys.
*
* @returns Array keys.
*/
public keys(): ArrayIterator<number> {
return (arrays.get(this) as T[]).keys();
}
/**
* Get array values.
*
* @returns Array values.
*/
public values(): ArrayIterator<T> {
return (arrays.get(this) as T[]).values();
}
/**
* Get array iterator.
*
* @returns Array iterator.
*/
public [Symbol.iterator](): ArrayIterator<T> {
return (arrays.get(this) as T[])[Symbol.iterator]();
}
/**
* To array, optionally slice.
*
* @param start Start index.
* @param end End index.
* @returns Sliced values.
*/
public toArray(start?: number, end?: number): T[] {
return (arrays.get(this) as T[]).slice(start, end);
}
/**
* Value getter.
*
* @returns Array values.
*/
public valueOf(): T[] {
return (arrays.get(this) as T[]).slice();
}
/**
* Check if array type.
*
* @param arg Variable.
* @returns Is array type.
*/
public static is(arg: unknown): arg is PLArray {
return (arg as PLType | null)?.[Symbol.toStringTag] === PLTYPE_ARRAY;
}
static {
const value = {
value: PLTYPE_ARRAY,
configurable: false,
enumerable: false,
writable: false,
} as const;
Object.defineProperty(this.prototype, Symbol.toStringTag, value);
Object.defineProperty(this.prototype, 'type', value);
}
}