HuaweiDemo/assets/script/framework/lodash.ts
2023-11-07 09:17:57 +08:00

638 lines
18 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { _decorator } from "cc";
const { ccclass } = _decorator;
@ccclass("Lodash")
export class Lodash {
/* class member could be defined like this */
// dummy = '';
/**
* 遍历 collection集合元素返回 predicate断言函数第一个返回真值的第一个元素
* @param {any} collection 一个用来迭代的集合
* @param {Function} predicate 每次迭代调用的函数。
* @returns 返回匹配元素,否则返回 undefined。
*/
public static find (collection: any, predicate: Function) {
var result;
if (!Array.isArray(collection)) {
collection = Lodash._toArray(collection);
}
result = collection.filter(predicate);
if (result.length) {
return result[0];
}
return undefined;
}
/**
* 调用 iteratee 遍历 collection(集合) 中的每个元素
* @param {any} collection 一个用来迭代的集合
* @param {Function} iteratee 每次迭代调用的函数。
*/
public static forEach(collection: any, iteratee: any) {
if (!Array.isArray(collection)) {
var array = Lodash._toArrayKey(collection);
array.forEach(function (value: any, index: number, arr: any[]) {
var key1 = value['key'];
var value1 = value['value'];
iteratee(value1, key1, collection);
});
} else {
collection.forEach(iteratee);
}
}
/**
* 深度拷贝
* @param {any} sObj 拷贝的对象
* @returns
*/
public static cloneDeep(sObj: any) {
if (sObj === null || typeof sObj !== "object") {
return sObj;
}
let s: any = {};
if (sObj.constructor === Array) {
s = [];
}
for (let i in sObj) {
if (sObj.hasOwnProperty(i)) {
s[i] = Lodash.cloneDeep(sObj[i]);
}
}
return s;
}
/**
* 创建一个数组, value 是 iteratee迭代函数遍历 collection集合中的每个元素后返回的结果。
* @param {Array|Object} collection 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数用来转换key
* @returns {Array} 返回一个组成集合数组
*/
public static map(collection: any, iteratee: any) {
if (!Array.isArray(collection)) {
collection = Lodash._toArray(collection);
}
let arr: any[] = [];
collection.forEach(function (value: any, index: number, array: []) {
arr.push(iteratee(value, index, array));
});
return arr;
}
/**
*
* @param srcObj
* @returns
*/
private static _toArrayKey(srcObj: { [x: string]: any; hasOwnProperty: (arg0: string) => any; }) {
var resultArr = [];
// to array
for (var key in srcObj) {
if (!srcObj.hasOwnProperty(key)) {
continue;
}
resultArr.push({ key: key, value: srcObj[key] });
}
return resultArr;
}
private static _toArray(srcObj: any) {
let resultArr: any[] = [];
// to array
for (var key in srcObj) {
if (!srcObj.hasOwnProperty(key)) {
continue;
}
resultArr.push(srcObj[key]);
}
return resultArr;
}
/**
* 遍历 collection集合元素返回 predicate断言函数返回真值 的所有元素的数组。
* @param {Array|Object} collection 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数用来转换key
* @returns 返回一个新的过滤后的数组。
*/
public static filter(collection: any, iteratees: Function) {
if (!Array.isArray(collection)) {
collection = Lodash._toArray(collection);
}
return collection.filter(iteratees);
}
/**
* 执行深比较来确定两者的值是否相等。
* @param {any}x
* @param {any}y
* @returns {boolean} 如果 两个值完全相同,那么返回 true否则返回 false。
*/
public static isEqual(x: any, y: any): boolean {
var in1 = x instanceof Object;
var in2 = y instanceof Object;
if (!in1 || !in2) {
return x === y;
}
if (Object.keys(x).length !== Object.keys(y).length) {
return false;
}
for (var p in x) {
var a = x[p] instanceof Object;
var b = y[p] instanceof Object;
if (a && b) {
return Lodash.isEqual(x[p], y[p]);
} else if (x[p] !== y[p]) {
return false;
}
}
return true;
}
/**
* 接收一个要移除值的数组。
* @param {Array} array 修改的数组
* @param {Array} value 移除值的数组
* @param {Function} comparator comparator比较器调用每个元素。
* @returns
*/
public static pullAllWith(array: any[], value: any[], comparator: Function) {
value.forEach(function (item) {
var res = array.filter(function (n) {
return comparator(n, item);
});
res.forEach(function (item) {
var index = array.indexOf(item);
if (array.indexOf(item) !== -1) {
array.splice(index, 1);
}
});
});
return array;
}
/**
* 返回当前时间戳
* @returns
*/
public static now() {
return Date.now();
}
/**
* 接收一个要移除值的数组。
* @param {Array} array 修改的数组
* @param {Array} value 移除值的数组
* @returns
*/
public static pullAll(array: any[], value: any) {
value.forEach(function (item: any) {
var index = array.indexOf(item);
if (array.indexOf(item) !== -1) {
array.splice(index, 1);
}
});
return array;
}
/**
* 从右到左遍历集合中每一个元素的。
* @param {Array|Object} collection 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
*/
public static forEachRight(collection: [] | {}, iteratee: Function) {
if (!Array.isArray(collection)) {
collection = Lodash._toArray(collection);
}
//@ts-ignore
for (var i = collection.length - 1; i >= 0; i--) {
//@ts-ignore
var ret = iteratee(collection[i]);
if (!ret) break;
}
}
/**
* 检查字符串string是否以 target 开头。
* @param {string} str 要检索的字符串。
* @param {string}target 要检查的字符串。
* @param {number}position 检索的位置。
* @returns
*/
public static startsWith(str: string, target: string, position: number) {
str = str.substr(position);
return str.startsWith(target);
}
/**
* 检查字符串string是否以 target 结束。
* @param {string} str 要检索的字符串。
* @param {string}target 要检查的字符串。
* @param {number}position 检索的位置。
* @returns
*/
public static endsWith(str: string, target: string, position: number) {
str = str.substr(position);
return str.endsWith(target);
}
/**
* 移除数组中predicate断言返回为真值的所有元素
* @param {Array} array 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
* @returns
*/
public static remove(array: any[], predicate: Function) {
var result: any[] = [];
var indexes: any[] = [];
array.forEach(function (item, index) {
if (predicate(item)) {
result.push(item);
indexes.push(index);
}
});
Lodash._basePullAt(array, indexes);
return result;
}
private static _basePullAt(array: any[], indexes: any[]) {
var length = array ? indexes.length : 0;
var lastIndex = length - 1;
var previous;
while (length--) {
var index = indexes[length];
if (length === lastIndex || index !== previous) {
previous = index;
Array.prototype.splice.call(array, index, 1);
}
}
return array;
}
/**
* 返回第一个通过 predicate 判断为真值的元素的索引值
* @param {Array} array 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
* @param {number} fromIndex 开始查找索引值
* @returns
*/
public static findIndex(array: any[], predicate: Function, fromIndex: number) {
array = array.slice(fromIndex);
var i;
if (typeof predicate === "function") {
for (i = 0; i < array.length; i++) {
if (predicate(array[i])) {
return i;
}
}
} else if (Array.isArray(predicate)) {
for (i = 0; i < array.length; i++) {
var key = predicate[0];
var vaule = true;
//@ts-ignore
if (predicate.length > 1) {
vaule = predicate[1];
}
if (array[i][key] === vaule) {
return i;
}
}
} else {
for (i = 0; i < array.length; i++) {
if (array[i] === predicate) {
return i;
}
}
}
return -1;
}
/**
* 创建一个新数组将array与任何数组 或 值连接在一起。
* @returns
*/
public static concat() {
var length = arguments.length;
if (!length) {
return [];
}
var array = arguments[0];
var index = 1;
while (index < length) {
array = array.concat(arguments[index]);
index++;
}
return array;
}
/**
* 检查 value 是否是原始Number数值型 或者 对象。
* @param {any }value
* @returns
*/
public static isNumber(value: any) {
return typeof value === 'number';
}
/**
* 返回首次 value 在数组array中被找到的 索引值
* @param {Array}array
* @param {any}value
* @param {number} fromIndex
* @returns
*/
public static indexOf(array: any[], value: any, fromIndex: number) {
array = array.slice(fromIndex);
return array.indexOf(value);
}
/**
* 将 array 中的所有元素转换为由 separator 分隔的字符串。
* @param {any} array 要转换的数组
* @param {string} separator 分隔元素。
* @returns
*/
public static join(array: any[], separator: string) {
if (array === null) return '';
var result = '';
array.forEach(function (item) {
result += item + separator;
});
return result.substr(0, result.length - 1);
}
/**
* 根据separator 拆分字符串string。
* @param {string} str 要转换的数组
* @param {RegExp|string} separator 分隔元素。
* @param {number} limit 限制结果的数量。
* @returns
*/
public static split(str: string, separator: RegExp|string, limit: number) {
return str.split(separator, limit);
}
/**
* 计算 array 中的最大值。 如果 array 是 空的或者假值将会返回 undefined。
* @param {Array}array
* @returns
*/
public static max(array: any[]) {
if (array && array.length) {
var result;
for (var i = 0; i < array.length; i++) {
if (i === 0) {
result = array[0];
} else if (result < array[i]) {
result = array[i];
}
}
return result;
}
return undefined;
}
/**
* 创建一个切片数组去除array前面的n个元素。n默认值为1。
* @param {Array}array : 要查询的数组。
* @param {number}n 要去除的元素个数。
* @returns
*/
public static drop(array: any[], n: number) {
var length = array === null ? 0 : array.length;
if (!length) {
return [];
}
return array.slice(n);
}
/**
* 将array递归为一维数组。
* @param {Array} arr
* @returns
*/
public static flattenDeep(arr: any[]): any {
return arr.reduce(function (prev: any[], cur: any[]) {
return prev.concat(Array.isArray(cur) ? Lodash.flattenDeep(cur) : cur);
}, [ ]);
}
/**
* 创建一个去重后的array数组副本。使用了SameValueZero 做等值比较。只有第一次出现的元素才会被保留。
* @param {Array} array
* @returns
*/
public static uniq(array: any[]) {
let result: any[] = [];
array.forEach(function (item) {
if (result.indexOf(item) === -1) {
result.push(item);
}
});
return result;
}
/**
* 检查 value 是否是 NaN。
* @param {any}value
* @returns
*/
public static isNaN(value: any) {
// An `NaN` primitive is the only value that is not equal to itself.
// Perform the `toStringTag` check first to avoid errors with some
// ActiveX objects in IE.
return Lodash.isNumber(value) && value !== +value;
}
/**
* 将数组array拆分成多个 size 长度的区块,并将这些区块组成一个新数组
* @param {Array}array
* @param {number}size
* @returns
*/
public static chunk(array: any[], size: number) {
var length = array === null ? 0 : array.length;
if (!length || size < 1) {
return [];
}
var result = [];
while (array.length > size) {
result.push(array.slice(0, size));
array = array.slice(size);
}
result.push(array);
return result;
}
/**
* 转换 value 为一个有限数字
* @param {any} value
* @returns
*/
public static toFinite(value: any) {
var INFINITY = 1 / 0;
var MAX_INTEGER = 1.7976931348623157e+308;
if (!value) {
return value === 0 ? value : 0;
}
value = Number(value);
if (value === INFINITY || value === -INFINITY) {
var sign = (value < 0 ? -1 : 1);
return sign * MAX_INTEGER;
}
return value === value ? value : 0;
}
/**
* 判断是否为对象
* @param {any}value
* @returns {boolean}
*/
public static isObject(value: any) {
var type = typeof value;
return value !== null && (type === 'object' || type === 'function');
}
public static MAX_SAFE_INTEGER = 9007199254740991;
/**
*
* @param value
* @returns
*/
public static isLength(value: any) {
return typeof value === 'number' &&
value > -1 && value % 1 === 0 && value <= Lodash.MAX_SAFE_INTEGER;
}
public static _isArrayLike(value: []) {
return value !== null && Lodash.isLength(value.length) /*&& !isFunction(value)*/;
}
/**
* 返回数组总符合条件的最大值
* @param {Array} array 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
* @returns {Object} 返回最大值
*/
public static maxBy(array: any[], predicate: Function) {
if (array && array.length) {
var result;
var objResult;
for (var i = 0; i < array.length; i++) {
if (i === 0) {
result = predicate(array[0]);
objResult = array[0];
} else if (result < array[i]) {
result = (array[i]);
objResult = array[i];
}
}
return objResult;
}
return undefined;
}
/**
* 返回数组总符合条件的最小值
* @param {Array} array 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
* @returns {Object} 返回最小值
*/
public static minBy(array: any[], predicate: Function) {
if (array && array.length) {
let result;
let objResult;
for (var i = 0; i < array.length; i++) {
if (i === 0) {
result = predicate(array[0]);
objResult = array[0];
} else if (result > array[i]) {
result = predicate(array[i]);
objResult = array[i];
}
}
return objResult;
}
return undefined;
}
/**
* 返回复合迭代函数的总和
* @param {Array|Object} collection 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数
* @returns {Object} 返回总和
*/
public static sumBy(collection: [] | {}, predicate: Function) {
let sum: number = 0;
for (let key in collection) {
//@ts-ignore
sum += predicate(collection[key]);
}
return sum;
}
/**
* 返回复合迭代函数的次数
* @param {Array|Object} collection 一个用来迭代的集合.
* @param {Function} predicate 一个迭代函数用来转换key
* @returns {Object} 返回一个组成集合对象
*/
public static countBy(collection: [] | {}, predicate: Function) {
let objRet: {[key: string]: number} = {};
for (let key in collection) {
let value: any = predicate(key);
if (objRet.hasOwnProperty(value)) {
objRet[value] += 1;
} else {
objRet[value] = 1;
}
}
return objRet;
}
}