1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/src/common/Utils.ts

320 lines
8.0 KiB
TypeScript
Raw Normal View History

2016-03-13 05:19:24 +08:00
export class Utils {
static GUID(): string {
2022-04-05 01:37:31 +08:00
const s4 = (): string =>
2023-09-12 00:57:51 +08:00
Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
2019-07-28 04:56:12 +08:00
return s4() + s4() + '-' + s4() + s4();
}
2018-12-02 19:22:05 +08:00
static chunkArrays<T>(arr: T[], chunkSize: number): T[][] {
const R = [];
for (let i = 0; i < arr.length; i += chunkSize) {
R.push(arr.slice(i, i + chunkSize));
}
return R;
}
2016-03-13 05:19:24 +08:00
static wait(time: number): Promise<unknown> {
return new Promise((resolve): void => {
setTimeout(resolve, time);
});
}
2021-04-10 16:51:33 +08:00
static removeNullOrEmptyObj<T extends { [key: string]: any }>(obj: T): T {
if (typeof obj !== 'object' || obj == null) {
return obj;
}
const keys = Object.keys(obj);
for (const key of keys) {
if (obj[key] !== null && typeof obj[key] === 'object') {
if (Utils.removeNullOrEmptyObj(obj[key])) {
if (Object.keys(obj[key]).length === 0) {
delete obj[key];
}
}
} else if (obj[key] === null) {
delete obj[key];
}
}
return obj;
}
static clone<T>(object: T): T {
return JSON.parse(JSON.stringify(object));
}
static shallowClone<T>(object: T): T {
const c: any = {};
for (const e of Object.entries(object)) {
c[e[0]] = e[1];
}
return c;
}
static zeroPrefix(value: string | number, length: number): string {
2018-11-18 03:15:48 +08:00
const ret = '00000' + value;
return ret.substr(ret.length - length);
}
/**
* Checks if the two input (let them be objects or arrays or just primitives) are equal
*/
2022-12-29 02:12:18 +08:00
static equalsFilter(object: any, filter: any, skipProp: string[] = []): boolean {
if (typeof filter !== 'object' || filter == null) {
return object === filter;
2017-07-15 18:47:11 +08:00
}
2018-05-29 02:03:12 +08:00
if (!object) {
return false;
}
2020-02-05 02:37:47 +08:00
if (Array.isArray(object) && object.length !== filter.length) {
return false;
}
2017-07-08 18:43:42 +08:00
const keys = Object.keys(filter);
for (const key of keys) {
2022-12-29 02:12:18 +08:00
if (skipProp.includes(key)) {
continue;
}
if (typeof filter[key] === 'object') {
2022-12-29 02:12:18 +08:00
if (Utils.equalsFilter(object[key], filter[key], skipProp) === false) {
2017-07-08 18:43:42 +08:00
return false;
}
} else if (object[key] !== filter[key]) {
return false;
}
2016-03-13 05:19:24 +08:00
}
return true;
}
2023-09-04 00:35:57 +08:00
static toIsoString(d: number | Date) {
if (!(d instanceof Date)) {
d = new Date(d);
}
return d.getUTCFullYear() + '-' + d.getUTCMonth() + '-' + d.getUTCDate();
}
static makeUTCMidnight(d: number | Date) {
if (!(d instanceof Date)) {
d = new Date(d);
}
d.setUTCHours(0);
d.setUTCMinutes(0);
d.setUTCSeconds(0);
d.setUTCMilliseconds(0);
return d;
}
static renderDataSize(size: number): string {
2020-12-31 19:35:28 +08:00
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
let index = 0;
while (size > 1000 && index < postFixes.length - 1) {
size /= 1000;
index++;
}
return size.toFixed(2) + postFixes[index];
}
static getUnique(arr: any[]) {
return arr.filter((value, index, arr) => arr.indexOf(value) === index);
}
static createRange(from: number, to: number): Array<number> {
const arr = new Array(to - from + 1);
let c = to - from + 1;
while (c--) {
arr[c] = to--;
}
return arr;
}
public static canonizePath(path: string): string {
2020-01-08 05:17:54 +08:00
return path
2023-09-12 00:57:51 +08:00
.replace(new RegExp('\\\\', 'g'), '/')
.replace(new RegExp('/+', 'g'), '/');
2020-01-08 05:17:54 +08:00
}
static concatUrls(...args: string[]): string {
let url = '';
for (const item of args) {
if (item === '' || typeof item === 'undefined') {
continue;
}
2016-03-26 23:25:48 +08:00
const part = item.replace(new RegExp('\\\\', 'g'), '/');
if (part === '/' || part === './') {
continue;
}
2016-04-22 19:23:44 +08:00
url += part + '/';
}
url = url.replace(/(https?:\/\/)|(\/){2,}/g, '$1$2');
if (url.trim() === '') {
url = './';
2017-07-20 02:47:09 +08:00
}
return url.substring(0, url.length - 1);
}
public static updateKeys(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof targetObject[key] === 'undefined') {
return;
}
if (typeof targetObject[key] === 'object') {
Utils.updateKeys(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});
}
public static setKeys(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof targetObject[key] === 'object') {
Utils.setKeys(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});
}
public static setKeysForced(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof sourceObject[key] === 'object') {
if (typeof targetObject[key] === 'undefined') {
targetObject[key] = {};
}
Utils.setKeysForced(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});
}
public static isValidEnumInt(EnumType: any, value: number) {
return typeof EnumType[value] === 'string';
}
2020-02-05 02:37:47 +08:00
public static enumToArray(EnumType: any): { key: number; value: string }[] {
2022-04-05 01:37:31 +08:00
const arr: Array<{ key: number; value: string }> = [];
for (const enumMember in EnumType) {
2022-04-26 00:36:18 +08:00
// eslint-disable-next-line no-prototype-builtins
if (!EnumType.hasOwnProperty(enumMember)) {
continue;
}
const key = parseInt(enumMember, 10);
if (key >= 0) {
2022-12-29 02:12:18 +08:00
arr.push({key, value: EnumType[enumMember]});
}
}
return arr;
}
2016-04-22 19:23:44 +08:00
public static findClosest(num: number, arr: number[]): number {
let curr = arr[0];
let diff = Math.abs(num - curr);
2016-05-12 17:00:46 +08:00
arr.forEach((value): void => {
const newDiff = Math.abs(num - value);
2016-05-12 17:00:46 +08:00
if (newDiff < diff) {
diff = newDiff;
curr = value;
}
});
2016-05-12 17:00:46 +08:00
return curr;
}
2016-05-12 17:00:46 +08:00
public static findClosestinSorted(num: number, arr: number[]): number {
let curr = arr[0];
let diff = Math.abs(num - curr);
for (const item of arr) {
const newDiff = Math.abs(num - item);
if (newDiff > diff) {
break;
}
diff = newDiff;
curr = item;
}
return curr;
}
2022-04-26 00:09:06 +08:00
public static isUInt32(value: number, max = 4294967295): boolean {
value = parseInt('' + value, 10);
2019-02-03 11:22:51 +08:00
return !isNaN(value) && value >= 0 && value <= max;
}
public static isInt32(value: number): boolean {
value = parseFloat('' + value);
2019-02-03 11:22:51 +08:00
return !isNaN(value) && value >= -2147483648 && value <= 2147483647;
}
public static isFloat32(value: number): boolean {
2019-02-03 11:22:51 +08:00
const E = Math.pow(10, 38);
const nE = Math.pow(10, -38);
2022-04-05 01:37:31 +08:00
return (
2023-09-12 00:57:51 +08:00
!isNaN(value) &&
((value >= -3.402823466 * E && value <= -1.175494351 * nE) ||
(value <= 3.402823466 * E && value >= 1.175494351 * nE))
2022-04-05 01:37:31 +08:00
);
2019-02-03 11:22:51 +08:00
}
2021-01-17 06:37:14 +08:00
public static getAnyX(num: number, arr: any[], start = 0): any[][] {
if (num <= 0 || num > arr.length || start >= arr.length) {
return [];
}
if (num <= 1) {
return arr.slice(start).map((e): any[] => [e]);
2021-01-17 06:37:14 +08:00
}
if (num === arr.length - start) {
return [arr.slice(start)];
}
const ret: any[][] = [];
for (let i = start; i < arr.length; ++i) {
Utils.getAnyX(num - 1, arr, i + 1).forEach((a): void => {
2021-01-17 06:37:14 +08:00
a.push(arr[i]);
ret.push(a);
});
}
return ret;
}
2016-03-13 05:19:24 +08:00
}
2021-04-06 17:32:31 +08:00
export class LRU<V> {
2022-04-05 01:37:31 +08:00
data: { [key: string]: { value: V; usage: number } } = {};
2021-04-06 17:32:31 +08:00
2022-12-29 02:12:18 +08:00
constructor(public readonly size: number) {
}
2021-04-06 17:32:31 +08:00
set(key: string, value: V): void {
2022-12-29 02:12:18 +08:00
this.data[key] = {usage: Date.now(), value};
if (Object.keys(this.data).length > this.size) {
let oldestK = key;
let oldest = this.data[oldestK].usage;
for (const k in this.data) {
if (this.data[k].usage < oldest) {
oldestK = k;
oldest = this.data[oldestK].usage;
2021-04-06 17:32:31 +08:00
}
}
delete this.data[oldestK];
2021-04-06 17:32:31 +08:00
}
}
2021-04-06 17:32:31 +08:00
get(key: string): V {
if (!this.data[key]) {
return;
2021-04-06 17:32:31 +08:00
}
return this.data[key].value;
2021-04-06 17:32:31 +08:00
}
}