-
Notifications
You must be signed in to change notification settings - Fork 159
/
Copy pathutils.js
205 lines (170 loc) · 6.74 KB
/
utils.js
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
// utils.js: 存放工具类方法
import pkg from 'lodash';
import crypto from 'crypto';
import {naturalCompare} from './natsort.js';
const {cloneDeep} = pkg;
export function getTitleLength(title) {
return title.length; // 返回标题长度
}
export function getNowTime() {
return (new Date()).getTime()
}
export async function sleep(ms) {
// 模拟异步请求
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}
export function sleepSync(ms) {
const end = Date.now() + ms; // 获取当前时间并计算结束时间
while (Date.now() < end) {
// 阻塞式等待,直到时间到达
}
}
/**
* 计算文件内容的 hash 值
* @param {string} content - 文件内容
* @returns {string} - 文件内容的 hash 值
*/
export function computeHash(content) {
return crypto.createHash('sha256').update(content, 'utf8').digest('hex');
}
/**
* 将obj所有key变小写
* @param obj
*/
export function keysToLowerCase(obj) {
return Object.keys(obj).reduce((result, key) => {
const newKey = key.toLowerCase();
result[newKey] = obj[key]; // 如果值也是对象,可以递归调用本函数
return result;
}, {});
}
export const deepCopy = cloneDeep
const resolve = (from, to) => {
const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
if (resolvedUrl.protocol === 'resolve:') {
const {pathname, search, hash} = resolvedUrl;
return pathname + search + hash;
}
return resolvedUrl.href;
};
/**
* url拼接
* @param fromPath 初始当前页面url
* @param nowPath 相对当前页面url
* @returns {*}
*/
export const urljoin = (fromPath, nowPath) => {
fromPath = fromPath || '';
nowPath = nowPath || '';
return resolve(fromPath, nowPath);
};
export const urljoin2 = urljoin
export const joinUrl = urljoin
export function naturalSort(arr, key, customOrder = []) {
return arr.sort((a, b) => {
const aValue = a[key];
const bValue = b[key];
// 检查是否在自定义排序列表中
const aIndex = customOrder.findIndex((item) => aValue.includes(item));
const bIndex = customOrder.findIndex((item) => bValue.includes(item));
if (aIndex !== -1 && bIndex !== -1) {
// 如果都在自定义列表中,按自定义顺序排序
return aIndex - bIndex;
} else if (aIndex !== -1) {
// 如果只有a在自定义列表中,a优先
return -1;
} else if (bIndex !== -1) {
// 如果只有b在自定义列表中,b优先
return 1;
}
// 如果都不在自定义列表中,按自然顺序排序
// return aValue.localeCompare(bValue, 'zh-CN', {numeric: true, sensitivity: 'base'});
// return aValue.localeCompare(bValue, 'zh-CN', {numeric: true});
return naturalCompare(aValue, bValue);
});
}
// 海阔不支持Intl.Collator
/*
export function naturalSort(arr, key, customOrder = []) {
const collator = new Intl.Collator('zh-Hans-CN', {
numeric: true,
sensitivity: 'base',
});
return arr.sort((a, b) => {
const x = a[key] || '';
const y = b[key] || '';
// 1. 检查自定义顺序
const xIndex = customOrder.findIndex((item) => x.includes(item));
const yIndex = customOrder.findIndex((item) => y.includes(item));
if (xIndex !== -1 || yIndex !== -1) {
if (xIndex === -1) return 1; // x 不在自定义顺序中,y 在
if (yIndex === -1) return -1; // y 不在自定义顺序中,x 在
return xIndex - yIndex; // 两者都在自定义顺序中,按索引排序
}
// 2. 使用 `Intl.Collator` 进行自然排序
return collator.compare(x, y);
});
}
*/
export function naturalSortAny(arr, key, customOrder = []) {
return arr.sort((a, b) => {
const EQUAL = 0;
const GREATER = 1;
const SMALLER = -1;
const options = {caseSensitive: false};
const re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi;
const sre = /(^[ ]*|[ ]*$)/g;
const dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
const hre = /^0x[0-9a-f]+$/i;
const ore = /^0/;
const normalize = function normalize(value) {
const string = '' + value;
return options.caseSensitive ? string : string.toLowerCase();
};
const x = normalize(a[key]).replace(sre, '') || '';
const y = normalize(b[key]).replace(sre, '') || '';
// Check custom order first
const xIndex = customOrder.findIndex((item) => x.includes(item));
const yIndex = customOrder.findIndex((item) => y.includes(item));
if (xIndex !== -1 || yIndex !== -1) {
if (xIndex === -1) return GREATER; // x not in customOrder, y is
if (yIndex === -1) return SMALLER; // y not in customOrder, x is
return xIndex - yIndex; // Both in customOrder, compare their indices
}
// chunk/tokenize
const xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
const yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
// Return immediately if at least one of the values is empty.
if (!x && !y) return EQUAL;
if (!x && y) return GREATER;
if (x && !y) return SMALLER;
// numeric, hex or date detection
const xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x));
const yD = parseInt(y.match(hre)) || (xD && y.match(dre) && Date.parse(y)) || null;
let oFxNcL, oFyNcL;
// first try and sort Hex codes or Dates
if (yD) {
if (xD < yD) return SMALLER;
else if (xD > yD) return GREATER;
}
// natural sorting through split numeric strings and default strings
for (let cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return isNaN(oFxNcL) ? GREATER : SMALLER;
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
}
if (oFxNcL < oFyNcL) return SMALLER;
if (oFxNcL > oFyNcL) return GREATER;
}
return EQUAL;
});
}