UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

382 lines (379 loc) 11.2 kB
import { getUnitPreviousRatio } from '../number/number.mjs'; function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /** * 判断数组是否全部相等 * @param {Array<number | string>} list - 数组 * @returns {Boolean} 是否全部相等 * * @example * isListAllEqual([0, 0, 0]) * * // true * * isListAllEqual([0, 0, 2]) * * // false */ function isListAllEqual() { var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; if (!list.length) return true; var value = list[0]; var _iterator = _createForOfIteratorHelper(list.slice(1)), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; if (item !== value) return false; } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return true; } /** * 获取对象的value列表,并输出大对象形式 * @param {Array<any>} data * @returns {Object} 处理后的对象 * * @example * * const data = [ * { * Project: 'x', * Request: 1, * Score: 'a' * }, * { * Project: 'y', * Request: 2, * Score: 'b' * }] * * getKeyValuesMap(data) * * // 结果为: * { * Project: ['x', 'y'], * Request: [1, 2], * Score: ['a', 'b'], * } * * // 也支持参数为带value属性的对象数组,如: * * const data = [ * { * Project: { * value: 'x' * } * },{ * Project: { * value: 'y' * } * }] * * // 结果为: * { * Project: ['x', 'y'] * } */ function getKeyValuesMap() { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; if (!data.length) return {}; var keys = Object.keys(data[0]); var keyValueMap = {}; data.forEach(function (item) { keys.forEach(function (key) { var _a; // 如果有value,就取value,否则直接取item[key] var value = ((_a = item[key]) === null || _a === void 0 ? void 0 : _a.value) || item[key]; if (keyValueMap[key]) { keyValueMap[key].push(value); } else { keyValueMap[key] = [value]; } }); }); return keyValueMap; } /** * 标记最大最小值 * @private * @param {object} params 参数对象 * @param {Array<number>} params.values 待处理的数组 * @param {number} params.value 当前值 * @param {Object} params.obj 迭代中的对象 * @returns {Object} 处理后的对象 */ function markMaxAndMinOfObj(_ref) { var values = _ref.values, value = _ref.value, obj = _ref.obj; var idx = values.indexOf(value); var lastIdx = values.indexOf(value); var newObj = Object.assign(Object.assign({}, obj), { idx: idx, lastIdx: lastIdx }); if (!isListAllEqual(values)) { var len = values.length; var isMax = idx === 0; var isSecondMax = idx === 1; var isMin = idx === len - 1; var isSecondMin = idx === len - 2; newObj = Object.assign(Object.assign({}, newObj), { isMax: isMax, isMin: isMin, isSecondMax: isSecondMax, isSecondMin: isSecondMin }); } return newObj; } /** * 获取相对上次的比例,会给输入的对象数组的每一项增加 ratio、previousValue 属性 * @param {Array<Object>} data - 输入数据 * @param {Object} preDataMap - 上次数据的map * @param {string} uniqKey - 唯一键 * * @example * const data = [{ * Project: { value: 'mj-match', name: 'Project' }, * Request: { * value: 854, * name: 'Request', * idx: 19, * lastIdx: 19, * isMax: false, * isMin: false, * isSecondMax: false, * isSecondMin: true, * }, * }]; * * const preDataMap = { * 'mj-match': { * Project: 'mj-match', * Request: 4, * Score: 91.81, * FirstLoadTime: 178, * WholePageTime: 1035, * ParseDomTime: 484, * DNSLinkTime: 0, * DOMTime: 414, * TCP: 0, * HTTP: 275, * BackEnd: 60, * CGIFailNum: 0, * ErrorLogNum: 0, * CGIRequestNum: 83, * }, * }; * * getPreviousRatio(data, preDataMap); * * // data会变成: * [{ * Project: { value: 'mj-match', name: 'Project' }, * Request: { * value: 854, * name: 'Request', * idx: 19, * lastIdx: 19, * isMax: false, * isMin: false, * isSecondMax: false, * isSecondMin: true, * * previousValue: 4, // 新增属性 * ratio: "+999+%" // 新增属性 * }, * }]; */ function getPreviousRatio() { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var preDataMap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var uniqKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Project'; data.forEach(function (item) { Object.keys(item).forEach(function (key) { var _a, _b; var obj = item[key]; if (typeof (obj === null || obj === void 0 ? void 0 : obj.value) === 'number') { var uniqVal = (_a = item[uniqKey]) === null || _a === void 0 ? void 0 : _a.value; var preValue = (_b = preDataMap === null || preDataMap === void 0 ? void 0 : preDataMap[uniqVal]) === null || _b === void 0 ? void 0 : _b[key]; if (preValue === undefined) { obj.ratio = ''; } else { obj.ratio = getUnitPreviousRatio(obj.value, preValue); obj.previousValue = preValue; } } }); }); } /** * 给对象数组的每一项,添加isMax、isMin、、isSecondMax、isSecondMin、idx、lastIdx等属性 * @param {Array<object>} data 原始数据 * @param {Array<string>} reverseScoreKeys - 逆序的key列表 * @returns {Object} 处理后的数据 * * @example * const data = [{ * ProjectName: { name: 'ProjectName', value: '麻将赛事' }, * PagePv: { name: 'PagePv', value: 2877 }, * }, { * ProjectName: { name: 'ProjectName', value: '斗地主赛事' }, * PagePv: { name: 'PagePv', value: 7 }, * }, * // ... * ]; * * getMaxAndMinIdx(data, []) * * // => * [{ * ProjectName: { name: 'ProjectName', value: '麻将赛事' }, * PagePv: { * name: 'PagePv', * value: 2877, * idx: 6, * lastIdx: 6, * isMax: false, * isMin: false, * isSecondMax: false, * isSecondMin: false, * }, * }]; * */ function getMaxAndMinIdx() { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var reverseScoreKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; if (!data.length) return []; var keys = Object.keys(data[0]); var keyValueMap = getKeyValuesMap(data); var parsedData = data.map(function (item) { var temp = Object.assign({}, item); keys.forEach(function (key) { var values = keyValueMap[key]; var itemInfo = item[key] || {}; if (values && typeof itemInfo.value === 'number') { if (reverseScoreKeys.indexOf(key) > -1) { values.sort(function (a, b) { if (a > b) return 1; if (a < b) return -1; return 0; }); } else { values.sort(function (a, b) { if (a > b) return -1; if (a < b) return 1; return 0; }); } temp[key] = markMaxAndMinOfObj({ values: values, value: itemInfo.value, obj: temp[key] }); } }); return temp; }); return parsedData; } /** * 拉平之前数据 * @param {Array<Object>} preDataList 之前的数据,作为对照 * @param {string} key 主键 * @returns {Object} preDataMap * * @example * const data = [{ * ProjectName: { name: 'ProjectName', value: '研发平台' }, * PagePv: { name: 'PagePv', value: 152 }, * PageUv: { name: 'PageUv', value: 7 }, * Score: { name: 'Score', value: 93.92 }, * PageDuration: { name: 'PageDuration', value: 1281.58 }, * PageError: { name: 'PageError', value: 2 }, * }]; * * flattenPreData(data, 'ProjectName'); * * // 输出 * { * 研发平台: { * ProjectName: '研发平台', * PagePv: 152, * PageUv: 7, * Score: 93.92, * PageDuration: 1281.58, * PageError: 2, * }, * }; */ function flattenPreData(preDataList, key) { var preDataMap = preDataList.reduce(function (acc, item) { var _a; acc[((_a = item[key]) === null || _a === void 0 ? void 0 : _a.value) || 'DEFAULT_KEY'] = Object.values(item).reduce(function (ac, it) { ac[it.name] = it.value; return ac; }, {}); return acc; }, {}); return preDataMap; } /** * 对比两个对象列表 * @param {Array<object>} list 现在数据 * @param {Array<object>} preList 参照数据 * @param {string} key 唯一key名称 * @returns {Array<object>} 对比结果,增加为list的每一项增加previousValue和ratio属性 * @example * const list = [ * { * ProjectName: { name: 'ProjectName', value: '脚手架' }, * PagePv: { name: 'PagePv', value: 544343 }, * PageUv: { name: 'PageUv', value: 225275 }, * } * ] * * const preList = [ * { * ProjectName: { name: 'ProjectName', value: '脚手架' }, * PagePv: { name: 'PagePv', value: 123123 }, * PageUv: { name: 'PageUv', value: 33333 }, * } * ] * * compareTwoList(list, preList, 'ProjectName') * * console.log(list) * * [ * { * ProjectName: { name: 'ProjectName', value: '脚手架' }, * PagePv: { * name: 'PagePv', * value: 544343, * ratio: '+342.1%', * previousValue: 123123 * }, * PageUv: { * name: 'PageUv', * value: 225275, * ratio: '+575.8%', * previousValue: 33333 * } * } * ] */ function compareTwoList(list, preList, key) { var preDataMap = flattenPreData(preList, key); getPreviousRatio(list, preDataMap, key); return list; } export { compareTwoList, flattenPreData, getKeyValuesMap, getMaxAndMinIdx, getPreviousRatio, isListAllEqual };