From 6871449d12f6253efcf9af5c54ea0d66ef755bf9 Mon Sep 17 00:00:00 2001 From: zhl Date: Fri, 17 Mar 2023 15:43:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=A4=9A=E4=BD=99=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/Extend.ts | 1034 ------------------------------------------- 1 file changed, 1034 deletions(-) delete mode 100644 src/utils/Extend.ts diff --git a/src/utils/Extend.ts b/src/utils/Extend.ts deleted file mode 100644 index a87e622..0000000 --- a/src/utils/Extend.ts +++ /dev/null @@ -1,1034 +0,0 @@ -/** - * 对数字进行补0操作 - * @param value 要补0的数值 - * @param length 要补的总长度 - * @return 补0之后的字符串 - */ -function zeroize(value: number | string, length: number = 2): string { - let str = "" + value; - let zeros = ""; - for (let i = 0, len = length - str.length; i < len; i++) { - zeros += "0"; - } - return zeros + str; -} - -/****************************************扩展Object****************************************/ -interface Object { - /** - * 返回一个浅副本的对象 - * 此对象会拷贝key value - * - * @memberOf Object - */ - clone?(): Object; - - /** - * 将数据拷贝到 to - * @param to 目标 - */ - copyto?(to: Object): void; - - /** - * 获取指定属性的描述,会查找当前数据和原型数据 - * @param property 指定的属性名字 - */ - getPropertyDescriptor?(property: string): PropertyDescriptor; - - zssign?(target: any): any; -} - -Object.defineProperties(Object.prototype, { - clone: { - value: function () { - let o = {}; - for (let n in this) { - // @ts-ignore - o[n] = this[n]; - } - return o; - }, - writable: true, - }, - getPropertyDescriptor: { - value: function (property: string): any { - let data = Object.getOwnPropertyDescriptor(this, property); - if (data) { - return data; - } - let prototype = Object.getPrototypeOf(this); - if (prototype) { - return prototype.getPropertyDescriptor(property); - } - return; - }, - writable: true, - }, - copyto: { - value: function (to: Object) { - for (let p in this) { - if (to.hasOwnProperty(p)) { - let data: PropertyDescriptor = to.getPropertyDescriptor!(p); - if (data) { - if (data.set || data.writable) { - // 可进行赋值 - // @ts-ignore - to[p] = this[p]; - } - } - } else { - // 本身没有这个属性 - // @ts-ignore - to[p] = this[p]; - } - } - }, - writable: true, - }, - zssign: { - value: function (target: Object) { - if (target === undefined || target === null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - - let output = Object(target); - for (let nextKey in this) { - if (!(nextKey in output)) { - // 本身没有这个属性 - output[nextKey] = this[nextKey]; - } - // else { - // let data: PropertyDescriptor = output.getPropertyDescriptor(nextKey); - // if (data) { - // if (data.set || data.writable) {// 可进行赋值 - // output[nextKey] = this[nextKey]; - // } - // } - // } - } - return output; - }, - writable: true, - }, -}); - -/****************************************扩展Math****************************************/ -interface Math { - /** - * 角度转弧度的乘数 - * Math.PI / 180 - * @type {number} - * @memberOf Math - */ - DEG_TO_RAD: number; - /** - * 弧度转角度的乘数 - * 180 / Math.PI - */ - RAD_TO_DEG: number; - /** - * 整圆的弧度 - */ - PI2: number; - /** - * 90°的弧度 - * - * @type {number} - * @memberOf Math - */ - PI_1_2: number; - - /** - * 让数值处于指定的最大值和最小值之间,低于最小值取最小值,高于最大值取最大值 - * @param value 要处理的数值 - * @param min 最小值 - * @param max 最大值 - */ - clamp?(value: number, min: number, max: number): number; - - /** - * 从最小值到最大值之间随机[min,max) - */ - random2?(min: number, max: number): number; -} - -Math.DEG_TO_RAD = Math.PI / 180; - -Math.RAD_TO_DEG = 180 / Math.PI; - -Math.PI2 = 2 * Math.PI; - -Math.PI_1_2 = Math.PI * 0.5; - -Math.clamp = (value, min, max) => { - if (value < min) { - value = min; - } - if (value > max) { - value = max; - } - return value; -}; - -Math.random2 = (min, max) => { - return min + Math.random() * (max - min); -}; - -/****************************************扩展Number********************************************/ -interface Number { - /** - * 对数字进行补0操作 - * @param length 要补的总长度 - * @return 补0之后的字符串 - */ - zeroize?(length: number): string; - - /** - * 数值介于,`min` `max`直接,包含min,max - * 即:[min,max] - * - * @param {number} min - * @param {number} max - * @returns {boolean} - */ - between?(min: number, max: number): boolean; -} - -Object.defineProperties(Number.prototype, { - zeroize: { - value: function (this: number, length: number) { - return zeroize(this, length); - }, - writable: true, - }, - between: { - value: function (this: number, min: number, max: number) { - return min <= this && max >= this; - }, - writable: true, - }, -}); - -/****************************************扩展String****************************************/ -interface String { - /** - * 替换字符串中{0}{1}{2}{a} {b}这样的数据,用obj对应key替换,或者是数组中对应key的数据替换 - */ - substitute?(args: any[]): string; - - /** - * 对数字进行补0操作 - * @param length 要补的总长度 - * @return 补0之后的字符串 - */ - zeroize?(length: number): string; - - /** - * 将一个字符串转换成一个很小几率重复的数值 - * 此方法hash的字符串并不一定唯一,慎用 - */ - hash?(): number; - - /** - * 获取字符串长度,中文方块字符算两个长度 - */ - trueLength?(): number; - - /** - * 中文字符个数 - * */ - cnLength?(): number; - - /** - * 比较版本号 - * */ - versionCompare?(target: string): number; - /** - * 将(start,end)之间的字符 [A-Za-z0-9_]替换成目标字符 - * @param start - * @param end - */ - repaceRange?(start: number, end: number, replaceChar: string): string; - /** - * 类似于padStart - * @param length - * @param fileChar - */ - leftPad?(length: number, fileChar?: string): string; -} - -Object.defineProperties(String.prototype, { - zeroize: { - value: function (length: number) { - return zeroize(this, length); - }, - writable: true, - }, - substitute: { - value: function (this: string) { - let len = arguments.length; - if (len > 0) { - let obj: IArguments; - if (len == 1) { - obj = arguments[0]; - if (typeof obj !== "object") { - obj = arguments; - } - } else { - obj = arguments; - } - if (obj instanceof Object && !(obj instanceof RegExp)) { - return this.replace( - /\{(?:%([^{}]+)%)?([^{}]+)\}/g, - function (match: string, handler: string, key: string) { - //检查key中,是否为%开头,如果是,则尝试按方法处理 - // @ts-ignore - let value = obj[key]; - if (handler && String.subHandler) { - //如果有处理器,拆分处理器 - let func = String.subHandler[handler]; - if (func) { - value = func(value); - } - } - return value !== undefined ? "" + value : match; - } - ); - } - } - return this.toString(); //防止生成String对象,ios反射String对象会当成一个NSDictionary处理 - }, - writable: true, - }, - hash: { - value: function () { - let len = this.length; - let hash = 5381; - for (let i = 0; i < len; i++) { - hash += (hash << 5) + this.charCodeAt(i); - } - return hash & 0x7fffffff; - }, - writable: true, - }, - trueLength: { - value: function () { - let arr: string[] = this.match(/[^x00-xff]/gi); - return this.length + (arr ? arr.length : 0); - }, - writable: true, - }, - cnLength: { - value: function () { - // /[\u2E80-\u9FBF] - let arr: string[] = this.match(/[^x00-xff]/gi); - return arr ? arr.length : 0; - }, - writable: true, - }, - repaceRange: { - value: function (start: number, end: number, repaceStr: string) { - this.replace(/\w/g, (match: string, i: number) => { - if (i < 3 || i >= 7) { - return match; - } else { - return "*"; - } - }); - }, - writable: true, - }, - leftPad: { - value: function (length: number, fillChar?: string) { - var padding = - length - this.length + 1 >= 0 ? length - this.length + 1 : 0; - return new Array(padding).join(fillChar ? fillChar : "0") + this; - }, - writable: true, - }, - versionCompare: { - value: function (target: string): number { - const GTR = 1; //大于 - const LSS = -1; //小于 - const EQU = 0; //等于 - if (!target) { - return GTR; - } - let v1arr = String(this) - .split(".") - .map(function (a) { - return parseInt(a); - }); - let v2arr = String(target) - .split(".") - .map(function (a) { - return parseInt(a); - }); - let arrLen = Math.max(v1arr.length, v2arr.length); - let result = 0; - - //检查空字符串,任何非空字符串都大于空字符串 - if (this.length == 0 && target.length == 0) { - return EQU; - } else if (this.length == 0) { - return LSS; - } else if (target.length == 0) { - return GTR; - } - //循环比较版本号 - for (let i = 0; i < arrLen; i++) { - result = versionComp(v1arr[i], v2arr[i]); - if (result == EQU) { - continue; - } else { - break; - } - } - return result; - - function versionComp(n1: number, n2: number) { - if (typeof n1 != "number") { - n1 = 0; - } - if (typeof n2 != "number") { - n2 = 0; - } - if (n1 > n2) { - return GTR; - } else if (n1 < n2) { - return LSS; - } else { - return EQU; - } - } - }, - writable: true, - }, -}); - -interface StringConstructor { - /** - * 对数字进行补0操作 - * @param value 要补0的数值 - * @param length 要补的总长度 - * @return 补0之后的字符串 - */ - zeroize?: (value: number, length: number) => string; - - /** - * substitute的回调函数 - * - * @type {Readonly<{ [index: string]: { (input: any): string } }>} - * @memberOf StringConstructor - */ - subHandler?: Readonly<{ [index: string]: { (input: any): string } }>; -} - -String.zeroize = zeroize; - -/****************************************扩展Date****************************************/ - -interface Date { - /** - * 格式化日期 - * - * @param {string} mask 时间字符串 - * @param {boolean} [local] 是否基于本地时间显示,目前项目,除了报错信息,其他时间都用UTC时间显示 - * @returns {string} 格式化后的时间 - */ - format(mask: string, local?: boolean): string; - - /** - * 增加n天 - * @param {number} days - * @return {Date} - */ - addDays(days: number): Date; - - /** - * 当前时间的当天的开始时间 - * @return {Date} - */ - dayStart(): Date; - /** - * 当前时间当天的结束时间 - * @return {Date} - */ - dayEnd(): Date; -} - -Object.defineProperties(Date.prototype, { - format: { - value: function (mask: string, local?: boolean) { - let d: Date = this; - // @ts-ignore - return mask.replace( - /"[^"]*"|'[^']*'|(?:d{1,2}|m{1,2}|yy(?:yy)?|([hHMs])\1?)/g, - function ($0: string) { - switch ($0) { - case "d": - return gd(); - case "dd": - return zeroize(gd()); - case "M": - return gM() + 1; - case "MM": - return zeroize(gM() + 1); - case "yy": - return (gy() + "").substr(2); - case "yyyy": - return gy(); - case "h": - return gH() % 12 || 12; - case "hh": - return zeroize(gH() % 12 || 12); - case "H": - return gH(); - case "HH": - return zeroize(gH()); - case "m": - return gm(); - case "mm": - return zeroize(gm()); - case "s": - return gs(); - case "ss": - return zeroize(gs()); - default: - return $0.substr(1, $0.length - 2); - } - } - ); - - function gd() { - return local ? d.getDate() : d.getUTCDate(); - } - - function gM() { - return local ? d.getMonth() : d.getUTCMonth(); - } - - function gy() { - return local ? d.getFullYear() : d.getUTCFullYear(); - } - - function gH() { - return local ? d.getHours() : d.getUTCHours(); - } - - function gm() { - return local ? d.getMinutes() : d.getUTCMinutes(); - } - - function gs() { - return local ? d.getSeconds() : d.getUTCSeconds(); - } - }, - writable: true, - }, - - addDays: { - value: function (days: number) { - this.setDate(this.getDate() + days); - return this; - }, - writable: true, - }, - dayStart: { - value: function () { - const timeTmp = new Date(this); - return timeTmp.setHours(0, 0, 0, 0); - }, - writable: true, - }, - dayEnd: { - value: function () { - const timeTmp = new Date(this); - return timeTmp.setHours(23, 59, 59, 59); - }, - writable: true, - }, -}); - -/****************************************扩展Array****************************************/ -const enum ArraySort { - /** - * 升序 - */ - ASC = 0, - /** - * 降序 - */ - DESC = 1, -} - -interface ArrayConstructor { - // binaryInsert(partArr: T[], item: T, filter: { (tester: T, ...args): boolean }, ...args); - SORT_DEFAULT: { number: 0; string: ""; boolean: false }; -} - -/** - * 用于对Array排序时,处理undefined - */ -Array.SORT_DEFAULT = { - number: 0, - string: "", - boolean: false, -}; -Object.freeze(Array.SORT_DEFAULT); - -interface Array { - /** - * 如果数组中没有要放入的对象,则将对象放入数组 - * - * @param {T} t 要放入的对象 - * @returns {number} 放入的对象,在数组中的索引 - * - * @member Array - */ - pushOnce?(t: T): number; - - /** - * - * 删除某个数据 - * @param {T} t - * @returns {boolean} true 有这个数据并且删除成功 - * false 没有这个数据 - */ - zremove?(t: T): boolean; - - /** - * 排序 支持多重排序 - * 降序, 升序 - * @param {(keyof T)[]} kArr 参数属性列表 - * @param {(boolean[] | ArraySort[])} [dArr] 是否降序,默认升序 - * @returns {this} - * - * @member Array - */ - multiSort?(kArr: (keyof T)[], dArr?: boolean[] | ArraySort[]): this; - - /** - * 默认排序 - * - * @param {string} [key] - * @param {boolean} [descend] - * - * @member Array - */ - doSort?(key?: keyof T, descend?: boolean | ArraySort): this; - - doSort?(descend?: boolean | ArraySort, key?: keyof T): this; - - /** - * 将数组克隆到to - * to的数组长度会和当前数组一致 - * - * @template T - * @param {Array} to - */ - cloneTo?(to: Array): void; - - /** - * 将数组附加到to中 - * - * @template T - * @param {Array} to - * - * @member ArrayConstructor - */ - appendTo?(to: Array): void; - - /** - * 移除数组index位置的元素, 比slice效率高 - * @param index - */ - spliceOne?(index: number): boolean; - - /** - * 随机排序 - */ - randomSort?(): void; - - /** - * 检查数组中是否含有另外一个object - * @param obj 与数组同类型的obj | 同类型的数组 | 指定child字段的值 | 指定child字段的数组 - * @param child 比较字段 - */ - contains?(obj: T | T[] | {} | {}[], child?: string): boolean; - - /** - * 将数组随机插入当前数组中 - * @param arr - */ - randomInsert?(arr: Array): void; - - /** - * 随机获取n个元素 - * @param count - */ - randomGet?(count?: number): T[]; - - /** - * 随机获取1个元素 - */ - randomOne?(): T | null; - - /** - * 随机移除n个元素 - * @param count - */ - randomRemove?(count?: number): T[]; - - /** - * 数组移动n位 - * @param n n > 0 右移, n<0 左移 - */ - moveElement?(n: number): T[]; - - /** - * 两个数组并集 - * @param arr - */ - union?(arr: T[]): T[]; - - /** - * 两个数组交集 - * @param arr - */ - intersect?(arr: T[]): T[]; - - /** - * 相对于arr的差集 - * @param arr - */ - difference?(arr: T[]): T[]; - - /** - * 转换成Map - * @param {string} key 用于生成map的key字段名 - * @return {Map} - */ - toMap?(key: string): Map; -} - -Object.defineProperties(Array.prototype, { - cloneTo: { - value: function (this: T[], b: any[]) { - b.length = this.length; - let len = this.length; - b.length = len; - for (let i = 0; i < len; i++) { - b[i] = this[i]; - } - }, - writable: true, - }, - appendTo: { - value: function (this: T[], b: any[]) { - let len = this.length; - for (let i = 0; i < len; i++) { - b.push(this[i]); - } - }, - writable: true, - }, - pushOnce: { - value: function (this: T[], t: T) { - let idx = this.indexOf(t); - if (!~idx) { - idx = this.length; - this.push(t); - } - return idx; - }, - writable: true, - }, - zremove: { - value: function (this: T[], t: T) { - let idx = this.indexOf(t); - if (~idx) { - this.splice(idx, 1); - return true; - } - return false; - }, - writable: true, - }, - doSort: { - value: function () { - let key: string = ""; - let descend: boolean; - let len = arguments.length; - - for (let i = 0; i < len; i++) { - let arg = arguments[i]; - let t = typeof arg; - if (t === "string") { - key = arg; - } else { - descend = !!arg; - } - } - if (key) { - return this.sort((a: any, b: any) => - descend ? b[key] - a[key] : a[key] - b[key] - ); - } else { - return this.sort((a: any, b: any) => (descend ? b - a : a - b)); - } - }, - writable: true, - }, - multiSort: { - value: function (kArr: string[], dArr?: boolean[] | boolean) { - let isArr = Array.isArray(dArr); - return this.sort((a: any, b: any): number => { - const def = Array.SORT_DEFAULT; - for (let idx = 0, len = kArr.length; idx < len; idx++) { - let key = kArr[idx]; - // @ts-ignore - let mode = isArr ? !!dArr[idx] : !!dArr; - let av = a[key]; - let bv = b[key]; - let typea = typeof av; - let typeb = typeof bv; - if (typea == "object" || typeb == "object") { - return 0; - } else if (typea != typeb) { - if (typea == "undefined") { - // @ts-ignore - bv = def[typeb]; - } else if (typeb == "undefined") { - // @ts-ignore - av = def[typea]; - } else { - return 0; - } - } - if (av < bv) { - return mode ? 1 : -1; - } else if (av > bv) { - return mode ? -1 : 1; - } else { - continue; - } - } - return 0; - }); - }, - writable: true, - }, - spliceOne: { - value: function (index: number): boolean { - if (index === -1 || index >= this.length) { - return false; - } - const len = this.length - 1; - for (let i = index; i < len; i++) { - this[i] = this[i + 1]; - } - this.length = len; - return true; - }, - writable: true, - }, - - randomSort: { - value: function () { - for ( - let j, x, i = this.length; - i; - j = (Math.random() * i) | 0, - x = this[--i], - this[i] = this[j], - this[j] = x - ) {} - }, - writable: true, - }, - contains: { - value: function (obj: T | T[] | {} | {}[], child?: string): boolean { - let result = false; - if (child) { - const isArr = Array.isArray(obj); - if (isArr) { - // @ts-ignore - if (obj[0].hasOwnProperty(child)) { - let set0 = new Set(); - // @ts-ignore - for (let s of obj) { - // @ts-ignore - set0.add(s[child]); - } - // @ts-ignore - let set1 = new Set(this.filter((x) => set0.has(x))); - return set0.size === set1.size; - } else { - // @ts-ignore - let set0 = new Set(obj); - let set1 = new Set(this.filter((x: {}) => set0.has(x))); - return set1.size === set0.size; - } - } else { - if (obj.hasOwnProperty(child)) { - for (let sub of this) { - if (sub.hasOwnProperty(child)) { - // @ts-ignore - if (sub[child] === obj[child]) { - result = true; - break; - } - } - } - } else { - for (let sub of this) { - if (sub.hasOwnProperty(child)) { - // @ts-ignore - if (sub[child] === obj) { - result = true; - break; - } - } - } - } - } - } else { - // 不指定 比较字段 的话, 只处理2种情况 - // 1: obj 为数组 - // 2: obj 不是数组 - if (Array.isArray(obj)) { - let set0 = new Set(obj); - // @ts-ignore - let set1 = new Set(this.filter((x) => set0.has(x))); - return set1.size === set0.size; - } else { - let idx = this.indexOf(obj); - return !!~idx; - } - } - return result; - }, - writable: true, - }, - randomInsert: { - value: function (arr: Array) { - const length = this.length; - arr.forEach((value) => { - this.splice(Math.random() * length, 0, value); - }); - }, - writable: true, - }, - randomGet: { - value: function (count: number = 1): T[] { - let shuffled: T[] = this.slice(0), - i = this.length, - min = i - count, - temp, - index; - if (min < 0) { - return shuffled; - } - while (i-- > min) { - index = Math.floor((i + 1) * Math.random()); - temp = shuffled[index]; - shuffled[index] = shuffled[i]; - shuffled[i] = temp; - } - return shuffled.slice(min); - }, - writable: true, - }, - randomOne: { - value: function (): T | null { - let results = this.randomGet(1); - if (results.length > 0) { - return results[0]; - } else { - return null; - } - }, - writable: true, - }, - randomRemove: { - value: function (count: number = 1): T[] { - let result = []; - while (count-- > 0 && this.length > 0) { - let index = (Math.random() * this.length) | 0; - result.push(...this.splice(index, 1)); - } - return result; - }, - writable: true, - }, - - moveElement: { - value: function (n: number): T[] { - if (Math.abs(n) > this.length) n = n % this.length; - return this.slice(-n).concat(this.slice(0, -n)); - }, - writable: true, - }, - - union: { - value: function (this: T[], b: any[]): T[] { - let a = this.concat(b); - return [...new Set(a)]; - }, - writable: true, - }, - - intersect: { - value: function (this: T[], b: any[]): T[] { - let set0 = new Set(b); - let set1 = new Set(this.filter((x) => set0.has(x))); - return [...set1]; - }, - writable: true, - }, - - difference: { - value: function (this: T[], b: any[]): T[] { - let set0 = new Set(b); - let set1 = new Set(this.filter((x) => !set0.has(x))); - return [...set1]; - }, - writable: true, - }, - - toMap: { - value: function (this: T[], key: string) { - let result: Map = new Map(); - for (const o of this) { - // @ts-ignore - result.set(o[key], o); - } - return result; - }, - writable: true, - }, -}); - -interface Map { - /** - * 只针对V为number的Map, 有值的话, 加上V, 没值则直接set - * V为其他类型时, 直接set - * @param key - * @param value - */ - inc?(key: K, value: V): number; -} - -Object.defineProperties(Map.prototype, { - inc: { - value: function (key: K, value: V) { - if (typeof value == "number") { - this.set(key, (this.get(key) || 0) + value); - } else { - this.set(key, value); - } - return this.get(key); - }, - }, -});