数组
uniqueArray
简单数组去重
typescript
/**
* 简单数组去重
* @param arr
* @returns
*/
export const uniqueArray = <T>(arr: T[]) => [...new Set(arr)];
const arr1 = [1,1,1,1 2, 3];
uniqueArray(arr); // [1,2,3]
uniqueArrayByKey
根据 key 数组去重
typescript
/**
* 根据key数组去重
* @param arr
* @param key
* @returns
*/
export function uniqeArrayByKey(arr: any[], key: string) {
const obj: Record<string, any> = {}
return arr.reduce((prev, item) => {
obj[item[key]] ? '' : (obj[item[key]] = true && prev.push(item))
return prev
}, [])
}
const arr = [
{ id: 1, parentid: 0 },
{ id: 2, parentid: 1 },
{ id: 3, parentid: 1 },
{ id: 3, parentid: 1 },
]
uniqeArrayByKey(arr, 'id')
/**
* [
{ id: 1, parentid: 0 },
{ id: 2, parentid: 1 },
{ id: 3, parentid: 1 },
];
*
*/
sortCompare
数组根据 key 排序
typescript
/**
* 排序
* arr: 所需排序的数组
* prop:排序的依据字段
* order:默认true -> 正序(小 -> 大) / false -> 倒序(大 -> 小)
*/
export const sortCompare = (arr: any[], prop: string | number, order = true) => {
return arr.sort(compare(prop, order))
}
function compare(prop: string | number, order: boolean) {
return (obj1: Record<string, any>, obj2: Record<string, any>) => {
let val1 = obj1[prop]
let val2 = obj2[prop]
if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
val1 = Number(val1)
val2 = Number(val2)
}
if (order) {
if (val1 < val2) return -1
else if (val1 > val2) return 1
else return 0
} else {
if (val1 > val2) return -1
else if (val1 < val2) return 1
else return 0
}
}
}
const arr = [
{ order: 1, name: '1' },
{ order: 10, name: '10' },
{ order: 3, name: '3' },
]
const sortArr = sortCompare(arr, order)
/**
* [
{ order: 1, name: '1' },
{ order: 3, name: '3' },
{ order: 10, name: '10' },
];
*
*/
multiFieldSort
数组根据多个字段排序
js
/**
* multiFieldSort(data, [{ field: 'age', order: 'desc' }, { field: 'name' }, { field: 'salary', order: 'desc' }])
* @param {*} arr
* @param {*} sortFields
* @returns
*/
export function multiFieldSort(arr, sortFields) {
return arr.sort((a, b) => {
for (let i = 0; i < sortFields.length; i++) {
let field = sortFields[i].field
let order = sortFields[i].order || 'asc'
if (a[field] < b[field]) {
return order === 'asc' ? -1 : 1
}
if (a[field] > b[field]) {
return order === 'asc' ? 1 : -1
}
}
return 0
})
}
getArrayLabelByValue
根据数组和 value 获取数组中的 label,没有返回 undefined
typescript
interface IParams {
arr: any[]
value: any
valueKey?: string
labelKey?: string
defaultValue?: string | number
}
/**
* 根据数组获取数组中的值
* @param param
* @returns
*/
export function getArrayLabelByValue({
arr,
value,
valueKey = 'value',
labelKey = 'label',
defaultValue = undefined,
}: IParams) {
if (!Array.isArray(arr)) {
throw new Error('Type requires an array')
}
const obj = arr.find(item => String(item[valueKey]) === String(value))
return obj ? obj[labelKey] : defaultValue
}
/**
* {
arr,
value,
valueKey = 'value',
labelKey = 'label',
defaultValue = undefined,
}
*/
const arr = [
{
label: 'Tom',
value: '1',
},
{
label: 'Lily',
value: '2',
},
]
getArrayLabelByValue({ arr, value: '2' }) // Lily
shuffle
洗牌算法随机
typescript
/**
* 洗牌算法随机
* @param arr
* @returns
*/
export function shuffle(arr: any[]) {
let result: any[] = [],
random: number
while (arr.length > 0) {
random = Math.floor(Math.random() * arr.length)
result.push(arr[random])
arr.splice(random, 1)
}
return result
}
const arr = [1, 2, 3]
shuffle(arr) // [2,3,1]
compact
去除数组中的无效/无用值
typescript
/**
* 去除数组中的无效/无用值
* @param arr
* @returns
*/
export function compact(arr: any[]) {
return arr.filter(Boolean)
}
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])
// [ 1, 2, 3, 'a', 's', 34 ]
countOccurrences
检测数值出现次数
typescript
/**
* 检测数值出现次数
* @param arr
* @param val
* @returns
*/
export function countOccurrences(arr: any[], val: any) {
return arr.reduce((a, v) => (v === val ? a + 1 : a), 0)
}
countOccurrences([1, 1, 2, 1, 2, 3], 1) // 3
flatten
指定深度扁平化数组
typescript
/**
* 指定深度扁平化数组
* @param arr
* @param depth
* @returns
*/
export function flatten(arr: any[], depth = 1): any[] {
return arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), [])
}
flatten([1, [2], 3, 4]) // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2) // [1, 2, 3, [4, 5], 6, 7, 8]
deepFlatten
递归扁平化数组
typescript
/**
* 递归扁平化数组
* @param arr
* @returns
*/
export function deepFlatten(arr: any[]): any[] {
return [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)))
}
deepFlatten([1, [2], [[3], 4], 5]) // [1,2,3,4,5]
difference
查找两个数组之间的差异
typescript
/**
* 查找两个数组之间的差异
* @param a
* @param b
* @returns
*/
export const difference = (a: any[], b: any[]) => {
const s = new Set(b)
return a.filter(x => !s.has(x))
}
difference([1, 2, 3], [1, 2, 4]) // [3]
indexOfAll
返回数组中某值的所有索引
typescript
/**
* 返回数组中某值的所有索引
* @param arr
* @param val
* @returns
*/
export const indexOfAll = (arr: any[], val: any) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), [])
indexOfAll([1, 2, 3, 1, 2, 3], 1) // [0,3]
indexOfAll([1, 2, 3], 4) // []
intersection
两数组的交集
typescript
/**
* 两数组的交集
* @param a
* @param b
* @returns
*/
export const intersection = (a: any[], b: any[]) => {
const s = new Set(b)
return a.filter(x => s.has(x))
}
intersection([1, 2, 3], [4, 3, 2]) // [2, 3]
intersectionBy
两数组都符合条件的交集
可用于在对两个数组的每个元素执行了函数之后,返回两个数组中存在的元素列表。
typescript
/**
* 两数组都符合条件的交集
* @param a
* @param b
* @param fn
* @returns
*/
export const intersectionBy = (a: any[], b: any[], fn: (arg0: any) => unknown) => {
const s = new Set(b.map(fn))
return a.filter(x => s.has(fn(x)))
}
intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor) // [2.1]
intersectionWith
先比较后返回交集
typescript
/**
* 先比较后返回交集
* @param a
* @param b
* @param comp
* @returns
*/
export const intersectionWith = (a: any[], b: any[], comp: (arg0: any, arg1: any) => any) =>
a.filter(x => b.findIndex(y => comp(x, y)) !== -1)
intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)) // [1.5, 3, 0]
addDeepProperty
给树结构每一层添加一层 deep 用以区分
typescript
export function addDeepProperty(tree, deep = 1) {
// 添加属性 deep 到当前层级
tree.deep = deep
// 递归处理子节点
if (tree.children && tree.children.length > 0) {
tree.children.forEach(child => {
addDeepProperty(child, deep + 1)
})
}
return tree
}