/* eslint-disable no-nested-ternary */ /* eslint-disable no-restricted-syntax */ /* eslint-disable guard-for-in */ /** * num 小于0,左缩进num*2个空格; 大于0,右缩进num*2个空格。 * @param {string} str 代码 * @param {number} num 缩进次数 * @param {number} len 【可选】缩进单位,空格数 */ export function indent(str, num, len = 2) { if (num === 0) return str const isLeft = num < 0; const result = []; let reg; let spaces = '' if (isLeft) { num *= -1 reg = new RegExp(`(^\\s{0,${num * len}})`, 'g') } else { for (let i = 0; i < num * len; i++) spaces += ' ' } str.split('\n').forEach(line => { line = isLeft ? line.replace(reg, '') : spaces + line result.push(line) }) return result.join('\n') } // 首字母大小 export function titleCase(str) { return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) } // 下划转驼峰 export function camelCase(str) { return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase()) } export function isNumberStr(str) { return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) } export const exportDefault = 'export default ' export const beautifierConf = { html: { indent_size: '2', indent_char: ' ', max_preserve_newlines: '-1', preserve_newlines: false, keep_array_indentation: false, break_chained_methods: false, indent_scripts: 'separate', brace_style: 'end-expand', space_before_conditional: true, unescape_strings: false, jslint_happy: false, end_with_newline: true, wrap_line_length: '110', indent_inner_html: true, comma_first: false, e4x: true, indent_empty_lines: true }, js: { indent_size: '2', indent_char: ' ', max_preserve_newlines: '-1', preserve_newlines: false, keep_array_indentation: false, break_chained_methods: false, indent_scripts: 'normal', brace_style: 'end-expand', space_before_conditional: true, unescape_strings: false, jslint_happy: true, end_with_newline: true, wrap_line_length: '110', indent_inner_html: true, comma_first: false, e4x: true, indent_empty_lines: true } } function stringify(obj) { return JSON.stringify(obj, (key, val) => { if (typeof val === 'function') { return `${val}` } return val }) } function parse(str) { JSON.parse(str, (k, v) => { if (v.indexOf && v.indexOf('function') > -1) { return eval(`(${v})`) } return v }) } export function jsonClone(obj) { return parse(stringify(obj)) } // 深拷贝对象 export function deepClone(obj) { const _toString = Object.prototype.toString // null, undefined, non-object, function if (!obj || typeof obj !== 'object') { return obj } // DOM Node if (obj.nodeType && 'cloneNode' in obj) { return obj.cloneNode(true) } // Date if (_toString.call(obj) === '[object Date]') { return new Date(obj.getTime()) } // RegExp if (_toString.call(obj) === '[object RegExp]') { const flags = [] if (obj.global) { flags.push('g') } if (obj.multiline) { flags.push('m') } if (obj.ignoreCase) { flags.push('i') } return new RegExp(obj.source, flags.join('')) } const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {} for (const key in obj) { result[key] = deepClone(obj[key]) } return result } /** * 将用户输入的连续单个数字合并为一个数 * @param {Array} expressions - 记录计算表达式的数组 * @returns {Array} 新的数组 */ export const mergeNumberOfExps = expressions => { const res = [] const isNumChar = n => /^[\d|\.]$/.test(n) for (let i = 0; i < expressions.length; i++) { if (i > 0 && isNumChar(expressions[i - 1]) && isNumChar(expressions[i])) { res[res.length - 1] += expressions[i] continue } res.push(expressions[i]) } return res } /** * 校验表达式是否符合计算法则 * @param {Array} expressions - 合并数字后的表达式数组 * @returns {Boolean} */ export const validExp = (expressions, mergeNum = true) => { const temp = mergeNum ? mergeNumberOfExps(expressions) : expressions const arr = temp.filter(t => !'()'.includes(t)) // 去括号后 length应该为奇数 并且第一个字符和最后一个字符应该为数字而非计算符号 if (temp.length % 2 === 0 || arr.length % 2 === 0 || Number.isNaN(+arr[0]) || Number.isNaN(+arr[arr.length - 1])) { return false } for (let i = 0; i < arr.length - 1; i += 2) { if (typeof(+arr[i]) !== 'number' || !Number.isNaN(+arr[i + 1])) return false } return true } /** * 中缀转后缀(逆波兰 Reverse Polish Notation) * @param {Array} exps - 中缀表达式数组 */ export const toRPN = exps => { const s1 = [] // 符号栈 const s2 = [] // 输出栈 const getTopVal = (stack) => stack.length > 0 ? stack[stack.length - 1] : null const levelCompare = (c1, c2) => { const getIndex = c => ['+-', '×÷', '()'].findIndex(t => t.includes(c)) return getIndex(c1) - getIndex(c2) } exps.forEach(t => { if (typeof t === 'string' && Number.isNaN(Number(t))) { // 是符号 if (t === '(') { s1.push(t) } else if (t === ')') { let popVal do { popVal = s1.pop() popVal !== '(' && s2.push(popVal) } while (s1.length && popVal !== '(') } else { let topVal = getTopVal(s1) if (!topVal) { // s1 为空 直接push s1.push(t) } else { while (topVal && topVal !== '(' && levelCompare(topVal, t) >= 0) { // 优先级 >= t 弹出到s2 s2.push(s1.pop()) topVal = getTopVal(s1) } s1.push(t) } } return } s2.push(t) // 数字直接入栈 }) while (s1.length) { s2.push(s1.pop()) } return s2 } /** * 计算后缀表达式的值 * @param {Array} rpnExps - 后缀表达式 */ export const calcRPN = rpnExps => { rpnExps = rpnExps.concat() const calc = (x, y, type) => { let a1 = Number(x), a2 = Number(y) switch (type) { case '+': return a1 + a2; case '-': return a1 - a2; case '×': return a1 * a2; case '÷': return a1 / a2; } } for (let i = 2; i < rpnExps.length; i++) { if ('+-×÷'.includes(rpnExps[i])) { let val = calc(rpnExps[i - 2], rpnExps[i - 1], rpnExps[i]) rpnExps.splice(i - 2, 3, val) i = i - 2 } } return rpnExps[0] } /** * 简易防抖函数 * @param {Function} func -防抖目标函数 * @param {Number} gap - 防抖时间间隔 */ export const debounce = (func, gap) => { let timer return function() { timer && clearTimeout(timer) timer = setTimeout(() => { func.apply(this, arguments) }, gap) } } //计算年或者月 export function getDateDay(Target, type, monthNum) { let date = new Date() let year = date.getFullYear() //获取当前日期的年份 let month = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) //获取当前日期的月份 let day = date.getDate() //获取当前日期的日 let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() let days = new Date(year, month, 0) days = days.getDate(); //获取当前日期中的月的天数 let year2 = year; let month2; if (Target == 2) { if (type == 5) { month2 = parseInt(month) + parseInt(monthNum) if (month2 > 12) { year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12)); month2 = parseInt(month2) % 12; } } else if (type == 4) { month2 = parseInt(month) - monthNum; if (month2 <= 0) { let absM = Math.abs(month2); year2 = parseInt(year2) - Math.ceil(absM / 12 == 0 ? 1 : parseInt(absM) / 12); month2 = 12 - (absM % 12); } } } else if (Target == 1) { month2 = parseInt(month) if (type == 5) { year2 = parseInt(year) + parseInt(monthNum) } else if (type == 4) { year2 = parseInt(year) - parseInt(monthNum) } } let day2 = day; let days2 = new Date(year2, month2, 0); days2 = days2.getDate(); if (day2 > days2) { day2 = days2; } if (month2 < 10) { month2 = '0' + month2; } let t2 = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds; return t2; } //计算日 export function getLaterData(days) { let date = new Date(); date.setDate(date.getDate() + days); let month = date.getMonth() + 1; let day = date.getDate(); let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() return date.getFullYear() + '-' + ('0' + month).slice(-2) + '-' + ('0' + day).slice(-2) + ' ' + hours + ':' + minutes + ':' + seconds; } export function getBeforeData(num) { let dateArray = [] //获取今天日期 let myDate = new Date() let hours = myDate.getHours() < 10 ? '0' + myDate.getHours() : myDate.getHours() let minutes = myDate.getMinutes() < 10 ? '0' + myDate.getMinutes() : myDate.getMinutes() let seconds = myDate.getSeconds() < 10 ? '0' + myDate.getSeconds() : myDate.getSeconds() let today = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate(); myDate.setDate(myDate.getDate() - num) let dateTemp; // 临时日期数据 let flag = 1; for (let i = 0; i < num; i++) { dateTemp = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate() dateArray.push({ date: dateTemp }) myDate.setDate(myDate.getDate() + flag); } dateArray.push({ date: today }) let arr = [] let newArr = [] dateArray.forEach(item => { arr.push(item.date.split('-')) }) for (let i = 0; i < arr.length; i++) { if (arr[i][1] < 10) { arr[i][1] = "0" + arr[i][1] } if (arr[i][2] < 10) { arr[i][2] = "0" + arr[i][2] } } for (let j = 0; j < arr.length; j++) { newArr.push(arr[j].join("-")) } return newArr[0] + ' ' + hours + ':' + minutes + ':' + seconds } export function getBeforeTime(type, val) { let date = new Date() if (type == 4 || type == 1) { date.setHours((Number(date.getHours()) - Number(val))) } else if (type == 5 || type == 2) { date.setMinutes((Number(date.getMinutes()) - Number(val))) } else if (type == 6 || type == 3) { date.setSeconds((Number(date.getSeconds()) - Number(val))) } return date } export function getLaterTime(type, val) { let date = new Date() if (type == 4 || type == 1) { date.setHours((Number(date.getHours()) + Number(val))) } else if (type == 5 || type == 2) { date.setMinutes((Number(date.getMinutes()) + Number(val))) } else if (type == 6 || type == 3) { date.setSeconds((Number(date.getSeconds()) + Number(val))) } return date }