一、数组解决
1. 数组去重
1. 纯数组去重(6种办法)
class ArrayToHeavy { // new Set去重 newSetHeavy(arr) { return Array.from(new Set(arr)) } // .indexOf或lastIndexOf去重 indexHeavy(arr) { let newArr = []; arr.forEach((val, index) => { newArr.indexOf(val) === -1 ? newArr.push(val) : ''; }); return newArr } // 通过filter过滤返回一个新数组在原数组中比照用indexof去重 filterHeavy(arr) { return arr.filter((item, index, self) => { return self.indexOf(item) === index; //比拟数组中每一项是否为其(indexof)首次查找的索引值(index) }) } // 通过splice扭转原数组去重 spliceHeavy(arr) { let len = arr.length; for (let i = 0; i < len; i++) { for (let j = i + 1; j < len; j++) { if (arr[i] == arr[j]) { arr.splice(j, 1); len--; j-- } } } } /* 相邻元素去重 这种办法首先调用了数组的排序办法sort(),而后依据排序后的后果进行遍历及相邻元素比对, 如果相等则跳过改元素,直到遍历完结 */ uniqueHeavy(arr) { if (!Array.isArray(arr)) { console.log('type error!') return } arr = arr.sort() let res = [] for (let i = 0; i < arr.length; i++) { if (arr[i] !== arr[i - 1]) { res.push(arr[i]) } } return res } /* 利用对象属性去重 创立空对象,遍历数组,将数组中的值设为对象的属性,并给该属性赋初始值1, 每呈现一次,对应的属性值减少1,这样,属性值对应的就是该元素呈现的次数了 */ ObjHeavy(arr) { if (!Array.isArray(arr)) { console.log('type error!') return } let res = [], obj = {} for (let i = 0; i < arr.length; i++) { if (!obj[arr[i]]) { res.push(arr[i]) obj[arr[i]] = 1 } else { obj[arr[i]]++ } } return res } } const ArrayToHeavy_handle = new ArrayToHeavy() console.log(ArrayToHeavy_handle.newSetHeavy([1, 1])) // [1]
2. 对象数组去重
1. 去重雷同id的对象
let person = [{ id: 0, name: "A" },{ id: 0, name: "b" }];let obj = {};let peon = person.reduce((cur, next) => { obj[next.id] ? "" : (obj[next.id] = true && cur.push(next)); return cur;}, []); //设置cur默认类型为数组,并且初始值为空的数组peon // [{ id: 0, name: "A" }]
2. 数组排序10种实用办法
{1} 冒泡排序
- 解释:冒泡排序算法就是顺次比拟大小,小的的大的进行地位上的替换。
- 实现原理:
当i=0的时候,外面的循环残缺执行,从j=0执行到j=6,这也就是第一遍排序,后果是将最大的数排到了最初,这一遍循环完结后的后果应该是[8,34,21,53,12,95
当i=1的时候,外面的循环再次残缺执行,因为最大的数曾经在最初了,没有必要去比拟数组的最初两项,这也是j<arr.length-1-i的奇妙之处,后果是[8,34,21,12,53,95]
说到这里,法则就分明了,每次将剩下数组外面最大的一个数排到最初面,当第一个循环执行到最初的时候,也就是i=6,此时,j=0,只须要比拟数组的第一和第二项,比拟结束,返回。
let arr=[8,95,34,21,53,12]; function sortarr(arr){ for(i=0;i<arr.length-1;i++){ for(j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){ var temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } return arr; } sortarr(arr); // [8,12,21,34,53,95]
(2) 抉择排序
解释:顺次找到残余元素最小值,搁置排好序的开端(第一个放在结尾)
在工夫复杂度上体现最稳固的排序算法之一,因为无论什么数据进去都是O(n²)的工夫复杂度,所以用到它的时候,数据规模越小越好。惟一的益处可能就是不占用额定的内存空间function selectionSort(arr) {var len = arr.length;var minIndex, temp;for (var i = 0; i < len - 1; i++) { minIndex = i; for (var j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { //寻找最小的数 minIndex = j; //将最小数的索引保留 } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp;}return arr;}
3. 数组拷贝
(1) [].concat.apply([], 被拷贝的数组)
适宜解决一维数组
let a = [1,2];let b = [].concat.apply([], a);b[0] = 0;a // => [1, 2]b // => [0, 2]
4.解决二维数组
(1) 将间断的二维数组中的对应索引项合并为一个数组,返回合并后的二维数组
输出:var data = [[2001, 10, 20],[2002, 30 ,40],[2003, 50 ,60]]输入:[[2001, 2002, 2003],[10, 30, 50],[20, 40, 60]]实现: var getBarData = []; data[0].map(item => { getBarData.push([]) }); data.forEach((item, inx) => { for(var i = 0; i < data[0].length; i++) { getBarData[i].push(item[i]) } })
5. 按指定条件
查找数组中的元素
(1) 查找数组最大值
输出: let a = [1,2,3,4] 输入: 4
1. 利用Math办法通过apply 将数组元素一个一个拆分开来,而后在传递到Math.max()办法中Math.max.apply(null, a)2. Math.max(...a)3. 利用sort办法 let resultArr = a.sort(function(a, b) { return b - a; }); resultArr[0] // 5
6. 按指定条件过滤数组
(1) 过滤数组中值为 false
的值
输出: let a = [0,0,false,null,3]输入: [3]
let b = a.filter(Boolean) // [3]
7. 类数组转为数组
(1) [].slice.call(obj) 或
Array.prototype.slice.call(obj) 或
Array.prototype.concat.apply([],obj)
[].slice.call({length:2,0:1,1:2}) // [1 ,2]Array.prototype.concat.apply([],{length:1,0:1}) // [1]
(2) Array.from(cArr) 或
[...obj]
Array.from({length:1,0:1}) // [1]
8.扁平化数组
输出: var arr = [[[1,2,3],[[4,5,6]]]]输入: [1,2,3,4,5,6]
(1) reduce递归法
var flatten = (arr) => { return arr.reduce((pre, next) => { return pre.concat(Array.isArray(next) ? flatten(next) : next); }, []) } flatten(arr) // [1,2,3,4,5,6]
二、对象解决
1. 将对象转为数组
利用Object.keys()
const obj = { "sex_wxx": "性别", "income_wxx": "支出", "age_wxx": "年龄" }; let arr = []; Object.keys(obj).forEach(v => { let o = {}; o[v] = obj[v]; arr.push(o) })console.log(arr) // [{sex_wxx: '性别'}, {income_wxx: '支出'},{age_wxx: '年龄'}]
- 利用Object.entries()
Object.entries(obj).forEach(item => { let o = {}o[item[0]] = item[1]arr.push(o)})
- Object.keys()和map()联合
Object.keys(obj).map(v => { return v = {[v]: obj[v]} })
2. 递归对象获取value
var obj = { a:{w:1,y:2,x:3},b:{s:4,j:5,x:6},c:{car:7,cat:8,mao:9}}function f(s){for(var i in s){if(typeof s[i]=="object"){f(s[i])}else{ console.log(s[i]); }}}f(obj) // 1,2,3,4,5,6,7,8,9
3. 判断两个对象是否相等
Object.entries({name:1}).toString() === Object.entries({name:1}).toString() // true
4. 从一个对象条件匹配另一个对象
用过滤(filter)判断(every)每一项是否符合条件
let obj = {name: 'ops'}let arr = [{name: 'q'}, {name: 'ops', kl: 'oop'}]var _key= Object.keys(obj)arr.filter(item=>_key.every(k=>obj[k]===item[k])) // {name: 'ops', kl: 'oop'}
5. 对象转为url参数拼接
输出:
{a:1,b:2}
输入:
a=1&b=2
function obj2strUrl (obj) { let str=""; for (let key in obj) { str = `${str}${key}=${obj[key]}&` }; str = str.substring(0, str.length-1); return str;}
反转:拼接的url参数转为对象
/** * @param {string} url * @returns {Object} */function param2Obj(url) { const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') if (!search) { return {} } const obj = {} const searchArr = search.split('&') searchArr.forEach(v => { const index = v.indexOf('=') if (index !== -1) { const name = v.substring(0, index) const val = v.substring(index + 1, v.length) obj[name] = val } }) return obj}
三、字符串解决
1. 将被字符串包裹的对象
转为js对象
输出 '{name: qwer, id: 1, ops: poi}',=> 输入 {name: 'qwer', id: '1', ops: 'poi'}
function strToObj(str) { let arr = str.replace(/{|}|\s*/g, '').split(','), obj = {} arr.forEach(val => { let i = val.indexOf(':') obj[val.substr(0, i)] = val.substr(i + 1);});return obj}console.log(strToObj('{name: qwer, id: 1, ops: poi}')) => {name: 'qwer', id: '1', ops: 'poi'}
2. 格式化string/number类型的日期
let date = '20220408000009';function f(str, type) {let i = 0,_type = type || 'xxxx-xx-xx xx:xx:xx'return _type.replace(/x/g, () => str[i++])}f(date)
3. 计算字符串宽度
(px)
// 1. 准确计算function computedTextWidth (text) { var canvas = document.createElement('canvas'); canvas.id = 'computedTextWidth'; canvas.style.cssText = 'visibility:hidden;position: absolute;left: -999em;top:-999em;'; document.body.appendChild(canvas); var context = canvas.getContext('2d'); context.font = '12px'; context.fillText(text, 0, 0); return context.measureText(text).width;}computedTextWidth('33333333') // 100// 2. 误差计算(差值为1/4)computedTextWidth(text, fontSize = 14) { let span = document.getElementById('computedTextWidth'); if (!span) { span = document.createElement('span'); span.id = 'computedTextWidth'; span.style.cssText = 'visibility:hidden;position: absolute;left: -999em;top:-999em;'; document.body.appendChild(span); } span.style.fontSize = `${fontSize}px`; span.innerHTML = text; return span.offsetWidth;};
4. 提取字符串中的数字
(1) match办法
var str = '123AAAA098'var numArr = str.match(/\d+/g) numArr // => ["123", "098"]
(2) replace办法
var s ="4500元,6,700";var num= s.replace(/[^0-9]/ig,"");num // 45006700
5. 提取字符串中的指定值(度量值
)
let str = '申请量 3 件,总量 3,541,98234,4.5,90% ,4.5%件。';str.match(/\d+(.\d+\%)|\d+(,\d+)|\d+(\.\d+)|\d+\%|\d+/img);str // ['3', '3,541', '98234', '4.5', '90%', '4.5%']
四、日期工夫类
1. 依据开始工夫 + 日/月/年数 计算截止日期
(1) 开始日期+天数=截止日期
export function getEndDay(dateTemp, days) { dateTemp = dateTemp.split("-") var nDate = new Date(dateTemp[1] + "-" + dateTemp[2] + "-" + dateTemp[0]) // 格式化工夫 var millSeconds = Math.abs(nDate) + days * 24 * 60 * 60 * 1000 var rDate = new Date(millSeconds) var year = rDate.getFullYear() var month = rDate.getMonth() + 1 if (month < 10) month = "0" + month var date = rDate.getDate() if (date < 10) date = "0" + date return year + "-" + month + "-" + date}应用: getEndDay('年-月-日', '天数')例: getEndDay('2021-11-11', '1') => '2021-11-12'
(2) 开始日期+月数=截止日期
export function getEndMonth(dtstr, n) { var s = dtstr.split("-") var yy = parseInt(s[0]) var mm = parseInt(s[1]) var dd = parseInt(s[2]) var dt = new Date(yy, mm, dd) var num=dt.getMonth() + parseInt(n) if(num/12>1){ yy+=Math.floor(num/12) mm=num%12 }else{ mm+=parseInt(n) } return yy + "-" + mm + "-" + dd } 应用: getEndMonth('年-月-日', '月数') 例: getEndMonth('2021-11-11', '1') => '2021-12-11'
(3)开始日期+年数=截止日期
export function getEndYear(date, years) { var now = new Date(date); var intYear = now.getFullYear() + parseInt(years); var intMonth = now.getMonth() + 1; //失常的月份, var intDay = now.getDate() - 1; //日期-1 if (intDay == 0) { intMonth--; //缩小一个月 if (intMonth == 0) { intYear--; //0:缩小一年 intMonth = 12; intDay = 31; } else if (intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) { intDay = 30; //4,6,9,11:30天 } else if (intMonth == 2) { intDay = 28; //2:28/29 if (intYear % 4 == 0) { intDay = 29; } } else { intDay = 31; //1,3,5,7,8,10,12 :31天 } } var strMonth = (intMonth) < 10 ? "0" + (intMonth).toString() : (intMonth).toString(); var strDay = (intDay) < 10 ? "0" + (intDay).toString() : (intDay).toString(); var strEndDate = intYear + "-" + strMonth + "-" + strDay; return strEndDate; } 应用: getEndYear('年-月-日', '月数') 例: getEndYear('2021-11-11', '1') => '2022-12-11'
2. 获取指定日期工夫
export function timeStremHandle() { let now = new Date() //以后日期 let nowDayOfWeek = now.getDay() //明天本周的第几天 let nowDay = now.getDate() //以后日 let nowMonth = now.getMonth() //以后月 let nowYear = now.getYear() //以后年 nowYear += (nowYear < 2000) ? 1900 : 0 let lastMonthDate = new Date() //上月日期 lastMonthDate.setDate(1) lastMonthDate.setMonth(lastMonthDate.getMonth() - 1) let lastYear = lastMonthDate.getYear() let lastMonth = lastMonthDate.getMonth() return {// 格式化日期:yyyy-MM-dd formatDate(date) { var myyear = date.getFullYear() var mymonth = date.getMonth() + 1 var myweekday = date.getDate() if (mymonth < 10) { mymonth = "0" + mymonth } if (myweekday < 10) { myweekday = "0" + myweekday } return (myyear + "-" + mymonth + "-" + myweekday) }, // 获取间断数字年月日 getNumDate(){ function formatNumber(n) { n = n.toString() return n[1] ? n : '0' + n } function formatDay (date) { var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() return [year, month, day].map(formatNumber).join('') + '' } 调用: formatDay(new Date()) // '20220923' },//取得某月的天数 getMonthDays(myMonth) { var monthStartDate = new Date(nowYear, myMonth, 1) var monthEndDate = new Date(nowYear, myMonth + 1, 1) var days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24) return days },//取得本季度的开始月份 getQuarterStartMonth() { var quarterStartMonth = 0 if (nowMonth < 3) { quarterStartMonth = 0 } if (2 < nowMonth && nowMonth < 6) { quarterStartMonth = 3 } if (5 < nowMonth && nowMonth < 9) { quarterStartMonth = 6 } if (nowMonth > 8) { quarterStartMonth = 9 } return quarterStartMonth },//取得本周的开始日期 getWeekStartDate() { var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek) return formatDate(weekStartDate) },//取得本周的进行日期 getWeekEndDate() { var weekEndDate = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek)) return formatDate(weekEndDate) },//取得本月的开始日期 getMonthStartDate() { var monthStartDate = new Date(nowYear, nowMonth, 1) return formatDate(monthStartDate) },//取得本月的进行日期 getMonthEndDate() { var monthEndDate = new Date(nowYear, nowMonth, getMonthDays(nowMonth)) return formatDate(monthEndDate) },//取得上月开始日期 getLastMonthStartDate() { var lastMonthStartDate = new Date(nowYear, lastMonth, 1) return formatDate(lastMonthStartDate) },//取得上月进行日期 getLastMonthEndDate() { var lastMonthEndDate = new Date(nowYear, lastMonth, getMonthDays(lastMonth)) return formatDate(lastMonthEndDate) },//取得本季度的开始日期 getQuarterStartDate() { var quarterStartDate = new Date(nowYear, getQuarterStartMonth(), 1) return formatDate(quarterStartDate) },//取得本季度的截止日期 getQuarterEndDate() { var quarterEndMonth = getQuarterStartMonth() + 2 var quarterStartDate = new Date(nowYear, quarterEndMonth, getMonthDays(quarterEndMonth)) return formatDate(quarterStartDate) }, //日期减 DateDiff(sDate1, sDate2) { var aDate, oDate1, oDate2, iDays aDate = sDate1.split("-") oDate1 = new Date(aDate[0], aDate[1] - 1, aDate[2]) aDate = sDate2.split("-") oDate2 = new Date(aDate[0], aDate[1] - 1, aDate[2]) iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24) if ((oDate1 - oDate2) < 0) { return -iDays } return iDays },// 最近一个月年月日 latelyTimeStrem() { var strem = new Date(now) strem.setDate(now.getDate() - 30) return { startDay: this.formatDate(new Date(nowYear, nowMonth, nowDay -30)), nowDay: this.formatDate(new Date(nowYear, nowMonth, nowDay)) } } }}
3. 获取以后工夫戳
export function getTime(type) { if (type === 'start') { return new Date().getTime() - 3600 * 1000 * 24 * 90 } else { return new Date(new Date().toDateString()) } }
4. 将工夫戳转为 {y}-{m}-{d} {h}:{i}:{s}
/** * @param {(Object|string|number)} time * @param {string} cFormat * @returns {string | null} * @description 工夫戳转为年月日时分秒 * @example parseTime(1656577144101) 2022-06-30 16:19:04; * 获取星期几:parseTime(1656577144101, '{y}-{m}-{d} {h}:{i}:{s}{a}'); 2022-06-30 16:19:04四 */export function parseTime(time, cFormat) { if (arguments.length === 0 || !time) { return null } const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' let date if (typeof time === 'object') { date = time } else { if ((typeof time === 'string')) { if ((/^[0-9]+$/.test(time))) { time = parseInt(time) } else { // https://stackoverflow.com/questions/4310953/invalid-date-in-safari time = time.replace(new RegExp(/-/gm), '/') } } if ((typeof time === 'number') && (time.toString().length === 10)) { time = time * 1000 } date = new Date(time) } const formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() } const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { const value = formatObj[key] // Note: getDay() returns 0 on Sunday if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } return value.toString().padStart(2, '0') }) return time_str}
5. 获取零碎时分秒
export function getSystemTime() { let timer = null setInterval(function () { let time = new Date() let hour = checkTime(time.getHours()) let minite = checkTime(time.getMinutes()) let second = checkTime(time.getSeconds()) function checkTime(i) { if (i < 10) return "0" + i return i } timer = hour + ":" + minite + ":" + second return timer }, 1000) }
6.计算两个日期之间的距离
const dayDif = (date1, date2) =>Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 86400000)dayDif(new Date("2022-11-3"), new Date("2022-2-1")) // 275
7. 查找日期位于一年中的第几天
const dayOfYear = (date) => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);dayOfYear(new Date()); // 311
五、 屏蔽浏览器控制台
1.写一个回调函数,让页面进行死循环
!function(){ var _0x1cbb = ["tor", "struc", "call", "ger", "con", "bug", "de", "apply"]; setInterval(check, 2e3); function check() { function doCheck(_0x1834ff) { if (('' + _0x1834ff / _0x1834ff)['length'] !== 0x1 || _0x1834ff % 0x14 === 0x0) { (function() {return !![]}[ _0x1cbb[0x4] + _0x1cbb[0x1] + _0x1cbb[0x0] ]( _0x1cbb[0x6] + _0x1cbb[0x5] + _0x1cbb[0x3] )[_0x1cbb[0x2]]()); } else { (function() {return ![]}[ _0x1cbb[0x4] + _0x1cbb[0x1] + _0x1cbb[0x0] ]( _0x1cbb[0x6] + _0x1cbb[0x5] + _0x1cbb[0x3] )[_0x1cbb[0x7]]()); } doCheck(++_0x1834ff); } try { doCheck(0) } catch(err) { } }; }();
六、加密算法
SHA加密
解释: SHA-1是一种数据加密算法,该算法的思维是接管一段明文,而后以一种不可逆的形式将它转换成一段(通常更小)密文,也能够简略的了解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输入序列即散列值(也称为信息摘要或信息认证代码)的过程。
function encodeUTF8 (s) { var i, r = [], c, x for (i = 0; i < s.length; i++) if ((c = s.charCodeAt(i)) < 0x80) r.push(c) else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F)) else { if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000, r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F)) else r.push(0xE0 + (c >> 12 & 0xF)) r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F)) } return r }function sha (s) { // sh1 编码 var data = new Uint8Array(encodeUTF8(s)) var i, j, t var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2) s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer) for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2) s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8) s[l - 1] = data.length << 3 var w = [], f = [ function () { return m[1] & m[2] | ~m[1] & m[3] }, function () { return m[1] ^ m[2] ^ m[3] }, function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3] }, function () { return m[1] ^ m[2] ^ m[3] } ], rol = function (n, c) { return n << c | n >>> (32 - c) }, k = [1518500249, 1859775393, -1894007588, -899497514], m = [1732584193, -271733879, null, null, -1009589776] m[2] = ~m[0], m[3] = ~m[1] for (i = 0; i < s.length; i += 16) { var o = m.slice(0) for (j = 0; j < 80; j++) w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1), t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0, m[1] = rol(m[1], 30), m.pop(), m.unshift(t) for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0 } t = new DataView(new Uint32Array(m).buffer) for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2) var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) { return (e < 16 ? "0" : "") + e.toString(16) }).join("") return hex }sha(123456); // 7c4a8d09ca3762af61e59520943dc26494f8941b