1. 简单数组去重
- 第一种方式:
使用 reduce 函数返回值是累加的结果,判断当前遍历值是否在其中。
function removeDuplicates(arr) {
let result = arr.reduce(function (init, current) {
if (init.indexOf(current) === -1) {
init.push(current);
}
return init;
}, []);
return result;
}
let myArray = ["a", "b", "a", "b", "c", "e", "e", "c", "d", "d", "d", "d"];
console.log(removeDuplicates(myArray));
- 第二种方式:
先使用排序,把相同的元素放到一起,然后再使用 reduce 方法让当前遍历对象跟前一个进行比较,相同就不加入,不同则加入。
function removeDuplicates(arr) {
let result = arr.sort().reduce((init, current) => {
if (init.length === 0 || init[init.length - 1] !== current) {
init.push(current);
}
return init;
}, []);
return result;
}
let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
console.log(removeDuplicates(arr));
- 第三种方式:
利用 indexOf 总是返回该项的第一个出现的索引,所以我们可以判断当前在过滤循环中的项是否是重复的。如果是,我们就不返回到由 filter()方法创建的新数组中。
function removeDuplicates(arr) {
let result = arr.filter((item, index) => {
return arr.indexOf(item) === index;
});
return result;
}
let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
console.log(removeDuplicates(arr));
2. 数组中对象去重
function removeDuplicates(arr) {
const tempObj = {};
let result = arr.reduce((init, current) => {
tempObj[current.name]
? ""
: (tempObj[current.name] = true && init.push(current));
return init;
}, []);
return result;
}
3. 扁平化嵌套数组
- 方式一:
使用 flat 方法,该方法接受一个可选参数,几维数组展开就把数字几作为参数,使用 Infinity 作为参数时可展开任意深度的嵌套数组
function flatArray(arr) {
return arr.flat();
}
- 方法二:
使用 reduce 方法,该方法仅适用于二维数组
function flatArray(arr) {
return arr.reduce((init, current) => init.concat(current), []);
}
4. 将数组转化为树形结构
let arr = [
{
id: 1,
name: "1",
pid: 0,
},
{
id: 2,
name: "1-1",
pid: 1,
},
{
id: 3,
name: "1-1-1",
pid: 2,
},
];
function toTree(data, parentId = 0) {
var itemArr = [];
for (var i = 0; i < data.length; i++) {
var node = data[i];
if (node.pid === parentId) {
var newNode = {
...node,
name: node.name,
id: node.id,
children: toTree(data, node.id),
};
itemArr.push(newNode);
}
}
return itemArr;
}
5. 格式化时间
const getDate = (timeStamp, format, type) => {
const d = new Date(timeStamp || 0);
const year = d.getFullYear();
const month = getHandledValue(d.getMonth() + 1);
const day = getHandledValue(d.getDate());
const hour = getHandledValue(d.getHours());
const minute = getHandledValue(d.getMinutes());
const second = getHandledValue(d.getSeconds());
let resStr = "";
if (!type) {
type = "/";
}
switch (format) {
case "yyyymmdd":
return [year, month, day].map(formatNumber).join(type);
case "yyyymm":
return [year, month].map(formatNumber).join(type);
case "mmdd":
return [month, day].map(formatNumber).join(type);
case "yyyy":
return year;
case "mm":
return [month].map(formatNumber);
case "dd":
return [day].map(formatNumber);
case "yyyymmddhhmmss":
return (
[year, month, day].map(formatNumber).join(type) +
" " +
[hour, minute, second].map(formatNumber).join(":")
);
case "yyyymmddhhmm":
return (
[year, month, day].map(formatNumber).join(type) +
" " +
[hour, minute].map(formatNumber).join(":")
);
case "hhmmss":
return [hour, minute, second].map(formatNumber).join(":");
case "hhmm":
return [hour, minute].map(formatNumber).join(":");
case "hh":
return [hour].map(formatNumber);
case "mi":
return [minute].map(formatNumber);
default:
return (
[year, month, day].map(formatNumber).join("/") +
" " +
[hour, minute, second].map(formatNumber).join(":")
);
}
};
const formatTime = (date) => {
let fmt = 'yyyy-MM-dd hh:mm:ss'
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, date.getFullYear())
}
for (let k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, o[k].toString().length == 1 ? '0' + o[k] : o[k])
}
}
return fmt
}
6. 获取相对时间
const getRelativeTime = (timeStamp) => {
const IS_MILLISECOND = isMillisecond(timeStamp);
if (IS_MILLISECOND) Math.floor((timeStamp /= 1000));
timeStamp = Number(timeStamp);
const currentTime = Math.floor(Date.parse(new Date()) / 1000);
const IS_EARLY = isEarly(timeStamp, currentTime);
let diff = currentTime - timeStamp;
if (!IS_EARLY) diff = -diff;
let resStr = "";
const dirStr = IS_EARLY ? "前" : "后";
if (diff <= 59) resStr = diff + "秒" + dirStr;
else if (diff > 59 && diff <= 3599)
resStr = Math.floor(diff / 60) + "分钟" + dirStr;
else if (diff > 3599 && diff <= 86399)
resStr = Math.floor(diff / 3600) + "小时" + dirStr;
else if (diff > 86399 && diff <= 2623859)
resStr = Math.floor(diff / 86400) + "天" + dirStr;
else if (diff > 2623859 && diff <= 31567859 && IS_EARLY)
resStr = getDate(timeStamp);
else resStr = getDate(timeStamp, "year");
return resStr;
};
7. 获取当前浏览器
const getExplorer = () => {
const ua = window.navigator.userAgent;
const isExplorer = (exp) => {
return ua.indexOf(exp) > -1;
};
if (isExplorer("MSIE")) return "IE";
else if (isExplorer("Firefox")) return "Firefox";
else if (isExplorer("Chrome")) return "Chrome";
else if (isExplorer("Opera")) return "Opera";
else if (isExplorer("Safari")) return "Safari";
};
8. 判断两个对象是否相等
const objEqual = (obj1, obj2) => {
const keysArr1 = Object.keys(obj1);
const keysArr2 = Object.keys(obj2);
if (keysArr1.length !== keysArr2.length) return false;
else if (keysArr1.length === 0 && keysArr2.length === 0) return true;
else
return !keysArr1.some((key) => obj1[key] != obj2[key]);
};
9. 百分比转小数
const percentageToDecimal = (num) => {
if (typeof num !== "number") num = Number(num);
let convert = num;
let unit = 100;
return convert / unit;
};
10. 小数转百分比
const decimalToPercentage = (num) => {
if (num && typeof num === "number") {
let convert = num;
let unit = 100;
return convert * unit;
} else {
return num;
}
};
11. 数组按指定份数分割
const splitArr = (data, senArrLen) => {
let data_len = data.length;
let arrOuter_len =
data_len % senArrLen === 0
? data_len / senArrLen
: parseInt(data_len / senArrLen + "") + 1;
let arrSec_len = data_len > senArrLen ? senArrLen : data_len;
let arrOuter = new Array(arrOuter_len);
let arrOuter_index = 0;
for (let i = 0; i < data_len; i++) {
if (i % senArrLen === 0) {
arrOuter_index++;
let len = arrSec_len * arrOuter_index;
arrOuter[arrOuter_index - 1] = new Array(data_len % senArrLen);
if (arrOuter_index === arrOuter_len)
data_len % senArrLen === 0
? (len = (data_len % senArrLen) + senArrLen * arrOuter_index)
: (len = (data_len % senArrLen) + senArrLen * (arrOuter_index - 1));
let arrSec_index = 0;
for (let k = i; k < len; k++) {
arrOuter[arrOuter_index - 1][arrSec_index] = data[k];
arrSec_index++;
}
}
}
return arrOuter;
};
12. 下载图片
const downloadImg = (imgsrc, name) => {
let image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png");
let a = document.createElement("a");
let event = new MouseEvent("click");
a.download = name || "photo";
a.href = url;
a.dispatchEvent(event);
};
image.src = imgsrc;
};
13. 拖拽移动
export const dragToMove = (dragDom, dragId) => {
var startEvt, moveEvt, endEvt;
if ("ontouchstart" in window) {
startEvt = "touchstart";
moveEvt = "touchmove";
endEvt = "touchend";
} else {
startEvt = "mousedown";
moveEvt = "mousemove";
endEvt = "mouseup";
}
var drag = dragDom;
var disX, disY, left, top, starX, starY;
var firstTime = "",
lastTime = "";
drag.addEventListener(startEvt, function (e) {
e.preventDefault();
document.getElementById(dragId).setAttribute("data-flag", false);
firstTime = new Date().getTime();
var e = e || window.event;
starX = e.touches ? e.touches[0].clientX : e.clientX;
starY = e.touches ? e.touches[0].clientY : e.clientY;
disX = starX - drag.offsetLeft;
disY = starY - drag.offsetTop;
document.addEventListener(moveEvt, moveFun);
document.addEventListener(endEvt, endFun);
});
function moveFun(e) {
var e = e || window.event;
left = (e.touches ? e.touches[0].clientX : e.clientX) - disX;
top = (e.touches ? e.touches[0].clientY : e.clientY) - disY;
if (left < 0) {
left = 0;
} else if (left > document.documentElement.clientWidth - drag.offsetWidth) {
left = document.documentElement.clientWidth - drag.offsetWidth;
}
if (top < 0) {
top = 0;
} else if (
top >
document.documentElement.clientHeight - drag.offsetHeight
) {
top = document.documentElement.clientHeight - drag.offsetHeight;
}
drag.style.left = left + "px";
drag.style.top = top + "px";
}
function endFun(e) {
document.removeEventListener(moveEvt, moveFun);
document.removeEventListener(endEvt, endFun);
lastTime = new Date().getTime();
if (lastTime - firstTime < 200) {
document.getElementById(dragId).setAttribute("data-flag", true);
if (endEvt == "touchend") {
document.getElementById(dragId).click();
}
}
}
};
14. 从 url 中解析出参数
const getParams = (url) => {
const keyValueArr = url.split("?")[1].split("&");
let paramObj = {};
keyValueArr.forEach((item) => {
const keyValue = item.split("=");
paramObj[keyValue[0]] = keyValue[1];
});
return paramObj;
};
15. 格式化金额
const formatNumber = (val = 0) => {
isNaN(val) ? (val = 0) : val;
return (val * 1).toLocaleString("zh", { minimumFractionDigits: 2 });
};
16. 加减乘法
const subtr = (arg1, arg2) => {
let num1 = arg1 || 0;
let num2 = arg2 || 0;
let r1, r2, m, n;
try {
r1 = num1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = num2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
n = r1 >= r2 ? r1 : r2;
return ((mul(num1, m) - mul(num2, m)) / m).toFixed(n);
};
const mul = (arg1, arg2) => {
let m = 0,
s1 = arg1.toString(),
s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
} catch (e) {}
try {
m += s2.split(".")[1].length;
} catch (e) {}
return (
(Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
Math.pow(10, m)
);
};
const accAdd = (arg1, arg2) => {
let num1 = arg1 || 0;
let num2 = arg2 || 0;
let r1, r2, m;
try {
r1 = num1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = num2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return (mul(num1, m) + mul(num2, m)) / m;
};
17. 自定义指令-按钮权限控制
Vue.directive("has", {
inserted: function (el, binding) {
if (!Vue.prototype.$has(binding.value)) {
el.parentNode.removeChild(el);
}
},
});
18. 自定义指令-防快速重复点击按钮
import Vue from "vue";
Vue.directive("preventReClick", {
inserted(el) {
el.addEventListener("click", () => {
if (!el.disabled) {
el.disabled = true;
setTimeout(() => {
el.disabled = false;
}, 2000);
}
});
},
});
19. 获取时间差
const getDateDiff = (startTime, endTime, diffType) => {
startTime = startTime.replace(/-/g, "/");
endTime = endTime.replace(/-/g, "/");
diffType = diffType.toLowerCase();
var sTime = new Date(startTime);
var eTime = new Date(endTime);
var divNum = 1;
switch (diffType) {
case "second":
divNum = 1000;
break;
case "minute":
divNum = 1000 * 60;
break;
case "hour":
divNum = 1000 * 3600;
break;
case "day":
divNum = 1000 * 3600 * 24;
break;
default:
break;
}
return parseInt((eTime.getTime() - sTime.getTime()) / parseInt(divNum));
};
20. 获取文件扩展名
const getFileType = (filePath) => {
var startIndex = filePath.lastIndexOf(".");
if (startIndex !== -1) {
return filePath.substring(startIndex + 1, filePath.length).toLowerCase();
} else {
return "";
}
};
21. 判断数组中是否有重复对象
const isRepeat = (arr) => {
const obj = {};
let flag = false;
arr.map((item) => {
obj[item.id] ? (flag = true) : (obj[item.id] = true);
});
return flag;
};
22. 压缩图片
export function compress(fileObj) {
return new Promise(resolve => {
function dataURLtoBlob(dataUrl) {
const arr = dataUrl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], fileObj.name, {
lastModified: fileObj.lastModifiedDate,
type: mime
})
}
if (typeof FileReader === 'undefined') {
console.log('当前浏览器内核不支持base64图标压缩')
resolve(fileObj)
}
try {
const reader = new FileReader()
const image = new Image()
reader.readAsDataURL(fileObj)
reader.onload = function (ev) {
image.src = String(ev.target.result)
image.onload = function () {
let imgWidth = image.width,
imgHeight = image.height
imgWidth = image.width
imgHeight = image.height
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = imgWidth
canvas.height = imgHeight
ctx.drawImage(image, 0, 0, imgWidth, imgHeight)
const fullQuality = canvas.toDataURL('image/jpeg', 0.05)
const blogData = dataURLtoBlob(fullQuality)
resolve(blogData)
}
}
} catch (e) {
resolve(fileObj)
}
})
}
23. 大数字转换为万/亿
export function transferNumber(num, point) {
let numStr = num.toString().split('.')[0]
if (numStr.length < 6) {
return numStr
} else if (numStr.length >= 6 && numStr.length <= 8) {
let decimal = numStr.substring(numStr.length - 4, numStr.length - 4 + point)
return parseFloat(parseInt(num / 10000) + '.' + decimal) +
'万'
} else if (numStr.length > 8) {
let decimal = numStr.substring(numStr.length - 8, numStr.length - 8 + point)
return parseFloat(parseInt(num / 100000000) + '.' + decimal) + '亿'
}
}