Skip to content

Commit c1b26ee

Browse files
committed
Optimize array.splice
1 parent bdd0dcc commit c1b26ee

1 file changed

Lines changed: 42 additions & 32 deletions

File tree

src/lualib/ArraySplice.ts

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice
2-
function __TS__ArraySplice<T>(this: void, list: T[], ...args: T[]): T[] {
3-
const len = list.length;
2+
function __TS__ArraySplice<T>(this: void, arr: T[], ...args: any[]): T[] {
3+
const len = arr.length;
44

55
const actualArgumentCount = select("#", ...args);
6-
const start = select(1, ...args)[0] as unknown as number;
7-
const deleteCount = select(2, ...args)[0] as unknown as number;
8-
9-
let actualStart: number;
6+
let start = args[0] as number;
7+
const deleteCount = args[1] as number;
108

119
if (start < 0) {
12-
actualStart = Math.max(len + start, 0);
13-
} else {
14-
actualStart = Math.min(start, len);
10+
start = len + start;
11+
if (start < 0) {
12+
start = 0;
13+
}
14+
} else if (start > len) {
15+
start = len;
1516
}
1617

17-
const itemCount = Math.max(actualArgumentCount - 2, 0);
18+
let itemCount = actualArgumentCount - 2;
19+
if (itemCount < 0) {
20+
itemCount = 0;
21+
}
1822

1923
let actualDeleteCount: number;
2024

@@ -23,56 +27,62 @@ function __TS__ArraySplice<T>(this: void, list: T[], ...args: T[]): T[] {
2327
actualDeleteCount = 0;
2428
} else if (actualArgumentCount === 1) {
2529
// ECMA-spec line 6: if number of actual arguments is 1
26-
actualDeleteCount = len - actualStart;
30+
actualDeleteCount = len - start;
2731
} else {
28-
actualDeleteCount = Math.min(Math.max(deleteCount || 0, 0), len - actualStart);
32+
actualDeleteCount = deleteCount || 0;
33+
if (actualDeleteCount < 0) {
34+
actualDeleteCount = 0;
35+
}
36+
if (actualDeleteCount > len - start) {
37+
actualDeleteCount = len - start;
38+
}
2939
}
3040

3141
const out: T[] = [];
3242

33-
for (let k = 0; k < actualDeleteCount; k++) {
34-
const from = actualStart + k;
43+
for (const k of $range(1, actualDeleteCount)) {
44+
const from = start + k;
3545

36-
if (list[from]) {
37-
out[k] = list[from];
46+
if (arr[from - 1] !== undefined) {
47+
out[k - 1] = arr[from - 1];
3848
}
3949
}
4050

4151
if (itemCount < actualDeleteCount) {
42-
for (let k = actualStart; k < len - actualDeleteCount; k++) {
52+
for (const k of $range(start + 1, len - actualDeleteCount)) {
4353
const from = k + actualDeleteCount;
4454
const to = k + itemCount;
4555

46-
if (list[from]) {
47-
list[to] = list[from];
56+
if (arr[from - 1]) {
57+
arr[to - 1] = arr[from - 1];
4858
} else {
49-
list[to] = undefined;
59+
arr[to - 1] = undefined;
5060
}
5161
}
52-
for (let k = len; k > len - actualDeleteCount + itemCount; k--) {
53-
list[k - 1] = undefined;
62+
for (const k of $range(len - actualDeleteCount + itemCount + 1, len)) {
63+
arr[k - 1] = undefined;
5464
}
5565
} else if (itemCount > actualDeleteCount) {
56-
for (let k = len - actualDeleteCount; k > actualStart; k--) {
57-
const from = k + actualDeleteCount - 1;
58-
const to = k + itemCount - 1;
66+
for (const k of $range(len - actualDeleteCount, start + 1, -1)) {
67+
const from = k + actualDeleteCount;
68+
const to = k + itemCount;
5969

60-
if (list[from]) {
61-
list[to] = list[from];
70+
if (arr[from - 1]) {
71+
arr[to - 1] = arr[from - 1];
6272
} else {
63-
list[to] = undefined;
73+
arr[to - 1] = undefined;
6474
}
6575
}
6676
}
6777

68-
let j = actualStart;
78+
let j = start + 1;
6979
for (const i of $range(3, actualArgumentCount)) {
70-
list[j] = select(i, ...args)[0];
80+
arr[j - 1] = args[i - 1];
7181
j++;
7282
}
7383

74-
for (let k = list.length - 1; k >= len - actualDeleteCount + itemCount; k--) {
75-
list[k] = undefined;
84+
for (const k of $range(arr.length, len - actualDeleteCount + itemCount + 1, -1)) {
85+
arr[k - 1] = undefined;
7686
}
7787

7888
return out;

0 commit comments

Comments
 (0)