-
Notifications
You must be signed in to change notification settings - Fork 169
Expand file tree
/
Copy pathalgorithmUtil.ts
More file actions
105 lines (92 loc) · 2.43 KB
/
algorithmUtil.ts
File metadata and controls
105 lines (92 loc) · 2.43 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
import type * as React from 'react';
/**
* Get index with specific start index one by one. e.g.
* min: 3, max: 9, start: 6
*
* Return index is:
* [0]: 6
* [1]: 7
* [2]: 5
* [3]: 8
* [4]: 4
* [5]: 9
* [6]: 3
*/
export function getIndexByStartLoc(min: number, max: number, start: number, index: number): number {
const beforeCount = start - min;
const afterCount = max - start;
const balanceCount = Math.min(beforeCount, afterCount) * 2;
// Balance
if (index <= balanceCount) {
const stepIndex = Math.floor(index / 2);
if (index % 2) {
return start + stepIndex + 1;
}
return start - stepIndex;
}
// One is out of range
if (beforeCount > afterCount) {
return start - (index - afterCount);
}
return start + (index - beforeCount);
}
/**
* We assume that 2 list has only 1 item diff and others keeping the order.
* So we can use dichotomy algorithm to find changed one.
*/
export function findListDiffIndex<T>(
originList: T[],
targetList: T[],
getKey: (item: T) => React.Key,
): { index: number; multiple: boolean } | null {
const originLen = originList.length;
const targetLen = targetList.length;
let shortList: T[];
let longList: T[];
if (originLen === 0 && targetLen === 0) {
return null;
}
if (originLen < targetLen) {
shortList = originList;
longList = targetList;
} else {
shortList = targetList;
longList = originList;
}
const notExistKey = { __EMPTY_ITEM__: true };
function getItemKey(item: T) {
if (item !== undefined) {
return getKey(item);
}
return notExistKey;
}
// Loop to find diff one
let diffIndex: number = null;
let multiple = Math.abs(originLen - targetLen) !== 1;
for (let i = 0; i < longList.length; i += 1) {
const shortKey = getItemKey(shortList[i]);
const longKey = getItemKey(longList[i]);
if (shortKey !== longKey) {
diffIndex = i;
multiple = multiple || shortKey !== getItemKey(longList[i + 1]);
break;
}
}
return diffIndex === null ? null : { index: diffIndex, multiple };
}
export function generateIndexesWithSticky(
startIndex: number,
endIndex: number,
stickyIndexes: number[],
) {
const indexArray: number[] = [];
for (let i = startIndex; i <= endIndex; i++) {
indexArray.push(i);
}
stickyIndexes.forEach((index) => {
if (index < startIndex || index > endIndex) {
indexArray.push(index);
}
});
return indexArray.sort((a, b) => a - b);
}