-
-
Notifications
You must be signed in to change notification settings - Fork 184
Expand file tree
/
Copy pathArraySplice.ts
More file actions
91 lines (76 loc) · 2.53 KB
/
ArraySplice.ts
File metadata and controls
91 lines (76 loc) · 2.53 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
import { __TS__CountVarargs } from "./CountVarargs";
// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice
export function __TS__ArraySplice<T>(this: T[], ...args: any[]): T[] {
const len = this.length;
const actualArgumentCount = __TS__CountVarargs(...args);
let start = args[0] as number;
const deleteCount = args[1] as number;
if (start < 0) {
start = len + start;
if (start < 0) {
start = 0;
}
} else if (start > len) {
start = len;
}
let itemCount = actualArgumentCount - 2;
if (itemCount < 0) {
itemCount = 0;
}
let actualDeleteCount: number;
if (actualArgumentCount === 0) {
// ECMA-spec line 5: if number of actual arguments is 0
actualDeleteCount = 0;
} else if (actualArgumentCount === 1) {
// ECMA-spec line 6: if number of actual arguments is 1
actualDeleteCount = len - start;
} else {
actualDeleteCount = deleteCount ?? 0;
if (actualDeleteCount < 0) {
actualDeleteCount = 0;
}
if (actualDeleteCount > len - start) {
actualDeleteCount = len - start;
}
}
const out: T[] = [];
for (const k of $range(1, actualDeleteCount)) {
const from = start + k;
if (this[from - 1] !== undefined) {
out[k - 1] = this[from - 1];
}
}
if (itemCount < actualDeleteCount) {
for (const k of $range(start + 1, len - actualDeleteCount)) {
const from = k + actualDeleteCount;
const to = k + itemCount;
if (this[from - 1]) {
this[to - 1] = this[from - 1];
} else {
this[to - 1] = undefined!;
}
}
for (const k of $range(len - actualDeleteCount + itemCount + 1, len)) {
this[k - 1] = undefined!;
}
} else if (itemCount > actualDeleteCount) {
for (const k of $range(len - actualDeleteCount, start + 1, -1)) {
const from = k + actualDeleteCount;
const to = k + itemCount;
if (this[from - 1]) {
this[to - 1] = this[from - 1];
} else {
this[to - 1] = undefined!;
}
}
}
let j = start + 1;
for (const i of $range(3, actualArgumentCount)) {
this[j - 1] = args[i - 1];
j++;
}
for (const k of $range(this.length, len - actualDeleteCount + itemCount + 1, -1)) {
this[k - 1] = undefined!;
}
return out;
}