Skip to content

数组

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
}

Released under the MIT License.