-
较常用
1. 类型判断
const typeJudge = (target, type = 'String') => {
return type === Object.prototype.toString.call(target).match(/(\w+)]/)[1]
}
// typeJudge(9, 'Number')
// true
2. 判断是否为空
1. 判空运算符??
((val ?? '') !== '')
2. 类型判断
const isEmpty = function(val) {
// null or undefined
if (val == null) return true
if (typeof val === 'boolean') return false
if (typeof val === 'number') return val === 0 ? false : !val
if (val instanceof Error) return val.message === ''
switch (Object.prototype.toString.call(val)) {
// String or Array
case '[object String]':
case '[object Array]':
return !val.length
// Map or Set or File
case '[object File]':
case '[object Map]':
case '[object Set]': {
return !val.size
}
// Plain Object
case '[object Object]': {
return !Object.keys(val).length
}
}
return false
}
// isEmpty()
// true
// isEmpty(null)
// true
// isEmpty(0)
// false
3. 数组去重
可去重基本数据类型,为对象时需传第二个参数,根据改字段名进行判断
const duplicateRemoval = (array, prop = 'id') => {
if (!typeJudge(array, 'Array' || array.length === 0)) {
return []
}
if (!typeJudge(array[0], 'Object')) {
return [...new Set(array)]
} else {
const temp = []
return array.reduce((acc, cur) => {
if (!temp.includes(cur[prop])) {
temp.push(cur[prop])
acc.push(cur)
}
return acc
}, [])
}
}
延申判断数组是否重复(只考虑基本数据类型)
// 判断单个数组是否存在重复值
const isRepeat = (array) => {
if (array.length === 0) {
return false
}
const result = [...new Set(array)]
return result.length !== array.length
}
// 判断两个数组是否存在重复值
const isRepeats = (arrayOne, arrayTwo) => {
if (arrayOne.length === 0 || arrayTwo.length === 0) {
return false
}
const temp = [].concat([...new Set(arrayOne)]).concat([...new Set(arrayTwo)])
return isRepeat(temp)
}
4. 数组转树结构
const listToTree = (data, propObj = {id: 'id', parentId: 'parentId', children: 'children'}) => {
if (!Array.isArray(data)) {
throw new Error('数据类型错误!')
}
const {id, parentId, children} = propObj
const result = []
const obj = {}
data.forEach(item => {
obj[item[id]] = item
})
data.forEach(item => {
const parent = obj[item[parentId]]
if (parent) {
if (!parent[children]) {
parent[children] = []
}
parent[children].push(item)
} else {
result.push(item)
}
})
return result
}
5. 组装二维数组
const assembleArray = (array, size = 10) => {
if (!array) {
return []
}
if (array.length <= size) {
return [array]
}
let index = 0
const result = []
do {
const temp = index + size > array.length ? array.length : index + size
result.push(array.slice(index, temp))
index = temp
} while (index < array.length)
return result
}
// assembleArray([1,2,3,4,5,6,7], 2)
// (4) [Array(2), Array(2), Array(2), Array(1)]
// 0: (2) [1, 2]
// 1: (2) [3, 4]
// 2: (2) [5, 6]
// 3: [7]
6. 生成指定长度随机数
const generateRandom = (n = 16, arr = []) => {
// 指定范围数
const range = (start, stop) => Array.from({ length: (stop - start) + 1 }, (_, i) => start + i)
// 大写字母
const capital = range(65, 90).map(value => String.fromCharCode(Number(value)))
// 小写字母
const lowercase = range(97, 122).map(value => String.fromCharCode(Number(value)))
// 数字
const number = range(0, 9)
const temp = arr.length > 0 ? arr : [].concat(capital).concat(lowercase).concat(number)
const tempLength = temp.length
const str = []
for (let i = 0; i < n; i++) {
const s = Math.floor(Math.random() * tempLength - 1)
str.push(temp[s < 0 ? 0 : s])
}
return str.join('')
}
// generateRandom(14)
// "nXUpAEdXOSx1ZvmW"
7. 字典数组转字典对象
const listToDictObj = (array, propObj = {key: 'key', value: 'value'}) => {
if (!Array.isArray(array) || array.length === 0) {
return {}
}
const dictObj = {}
const index = array.length - 1
for (let i = index; i > -1 ; i--) {
let propKey = array[i][propObj.key]
dictObj[propKey] = array[i][propObj.value]
}
return dictObj
}
// let arr = [{key: '01', value: 'vue'}, {key: '02', value: 'react'}]
// listToDictObj3(arr)
// {02: "react", 01: "vue"}
8. 字典数组转字典Map
需要多次字典取值时可快速转换,跟上述转对象相差不多
const arrayToMapX = (array, props = {key: 'id', value: 'label'}) => {
if (!Array.isArray(array)) return new Map()
const temp = []
array.forEach(value => {
if (value[props.key] && value[props.value]) {
temp.push([value[props.key], value[props.value]])
} else {
throw TypeError(`arrayToMap: array item is not prototype ${props.key} or ${props.value}`)
}
})
return new Map(temp)
}
8. 根据属性层级路径赋值对象属性值
可以用于设置对象多层级属性值
const objSetValue = (obj, path, value) => {
const temp = path.match(/\w+/g)
if (!temp || ((value ?? '') === '')) return obj
let pointer = obj
const length = temp.length
for (let i = 0; i < length; i++) {
if (i === length - 1) {
pointer[temp[i]] = value
} else {
if ((pointer[temp[i]] ?? '') === '') {
const flag = temp[i + 1].match(/^\d+$/)
pointer[temp[i]] = flag ? [] : {}
}
pointer = pointer[temp[i]]
}
}
return obj
}
// console.info(objSetValue({}, 'os.port', 300))
// console.info(objSetValue({}, 'arr.0.port', 300))
// console.info(objSetValue({}, 'arr.0.path', 'arr.0.path'))
-
较少用
1. 解析html标签
const parseHtmlLabel = (htmlLabel, title = 'title', tagType = 'tagType') => {
const resultObj = {}
const labels = [...htmlLabel.matchAll(/\s(\w+)=/g)].map(v => v[1])
const values = [...htmlLabel.matchAll(/\s\w+="([\w|\d|.|\/|:|;|+|,|=|__|\-|\u4e00-\u9fa5]*)"/g)].map(v => v[1])
if (labels.length > 0) {
for (let i = labels.length - 1; i > -1; i--) {
resultObj[labels[i]] = values[i]
}
}
const tempTitle = htmlLabel.match(/>([\w]*)</)
if (tempTitle && tempTitle.length > 0) {
resultObj[title] = tempTitle[1]
}
const tempTagType = htmlLabel.match(/<([\w]+)\s/)
if (tempTagType && tagType.length > 0) {
resultObj[tagType] = tempTagType[1]
}
return resultObj
}
// parseHtmlLabel('<input type="text" autocomplete="off" maxlength="50" placeholder="请输入人员姓名" class="el-input__inner"/>')
// {class: "el-input__inner", placeholder: "请输入人员姓名", maxlength: "50", autocomplete: "off", type: "text", …}
2. 计算时间范围差
const getTimeDifferenceObj = (startTime, endTime = new Date()) => {
const obj = {}
if (!startTime) return obj
const timestamp = +new Date(startTime) - +new Date(endTime) // 时间差的毫秒数
obj.flag = timestamp > 0
const timeDifference = Math.abs(timestamp)
// 计算出相差天数
const days = Math.floor(timeDifference / (24 * 3600 * 1000))
// 计算出小时数
const leave1 = timeDifference % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数
const hours = Math.floor(leave1 / (3600 * 1000))
// 计算相差分钟数
const leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数
const minutes = Math.floor(leave2 / (60 * 1000))
// 计算相差秒数
const leave3 = leave2 % (60 * 1000) // 计算分钟数后剩余的毫秒数
const seconds = Math.round(leave3 / 1000)
obj.day = days
obj.hours = hours
obj.minutes = minutes
obj.seconds = seconds
if (obj.flag) {
obj.label = `${days}天${hours}小时后到期`
} else {
obj.label = `已超期${days}天${hours}小时`
}
return obj
}
// getTimeDifferenceObj('2021-05-01 08:23:23')
//{
// day: 17
// flag: false
// hours: 6
// label: "已超期17天6小时"
// minutes: 7
// seconds: 17
//}