Skip to content

类型转换

arrayToTree

数组转树结构

typescript
interface IParams {
  arr: any[]
  idKey?: string
  parentKey?: string
  childrenKey?: string
  rootId?: string | number
}

/**
 * 数组转树结构
 * @param params
 * @returns
 */
export function arrayToTree(params: IParams) {
  const { arr, idKey = 'id', parentKey = 'pid', childrenKey = 'children', rootId = null } = params
  const result: any[] = []
  const itemMap: Record<string, any> = {}

  for (const item of arr) {
    const id = item[idKey]
    const pid = item[parentKey]

    if (!itemMap[id]) {
      itemMap[id] = {
        [childrenKey]: [],
      }
    }

    itemMap[id] = {
      ...item,
      children: itemMap[id][childrenKey],
    }

    const treeItem = itemMap[id]

    if (pid === rootId) {
      result.push(treeItem)
    } else {
      if (!itemMap[pid]) {
        itemMap[pid] = {
          children: [],
        }
      }
      itemMap[pid].children.push(treeItem)
    }
  }
  return result
}

/**
 *  const { arr, idKey = 'id', parentKey = 'pid', childrenKey = 'children', rootId = 0 } = params;
 */
const arr = [
  { id: 1, name: '部门1', pid: 0 },
  { id: 2, name: '部门2', pid: 1 },
  { id: 3, name: '部门3', pid: 1 },
  { id: 4, name: '部门4', pid: 3 },
  { id: 5, name: '部门5', pid: 4 },
]

const tree = arrayToTree({ arr })

/**
 * [
  {
    id: 1,
    name: '部门1',
    pid: 0,
    children: [
      {
        id: 2,
        name: '部门2',
        pid: 1,
        children: [],
      },
      {
        id: 3,
        name: '部门3',
        pid: 1,
        children: [
          // 结果 ,,,
        ],
      },
    ],
  },
];
 */

treeToList

树结构转数组

typescript
export function treeToList(tree) {
  let list = []

  function traverse(node) {
    list.push(node)

    if (node.children && node.children.length > 0) {
      for (let child of node.children) {
        traverse(child)
      }
    }
  }

  for (let root of tree) {
    traverse(root)
  }

  return list
}

base64ToBlob

base64 转 Blob 对象

typescript
/**
 *
 * @param { string } s base64
 * @returns Blob
 */
export function base64ToBlob(s: string): Blob {
  const arr = s.split(',')
  const mime = arr[0]?.match(/:(.*?);/)?.[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) u8arr[n] = bstr.charCodeAt(n)
  return new Blob([u8arr], { type: mime })
}

base64ToBlob('base64')

base64ToFile

base64 转 File 对象

typescript
/**
 *
 * @param { string } s base64
 * @param { string } filename 文件名
 * @returns
 */
export function base64ToFile(s: string, filename: string): File {
  const arr = s.split(',')
  const mime = arr[0]?.match(/:(.*?);/)?.[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) u8arr[n] = bstr.charCodeAt(n)
  return new File([u8arr], filename, { type: mime })
}

base64ToFile('base64', '文件名')

blobToUrl

Blob 转为 url

typescript
/**
 * Blob转为url
 * @param { Blob } blob Blob
 * @returns url
 */
export function blobToUrl(blob: Blob) {
  return window.URL.createObjectURL(blob)
}

blobToUrl(Blob)

fileToArrayBuffer

文件转 buffer

typescript
/**
 * 文件转buffer
 * @param { File } file 文件
 * @returns
 */
export function fileToArrayBuffer(file: File): Promise<Uint8Array> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()

    reader.onload = function () {
      const arrayBuffer = new Uint8Array(reader.result as any)
      resolve(arrayBuffer)
    }

    reader.onerror = reject

    reader.readAsArrayBuffer(file)
  })
}

fileToArrayBuffer(File)

fileToBlob

File 文件转为 Blob

typescript
/**
 * File文件转为Blob
 * @param { File } file 文件
 * @returns Blob
 */
export async function fileToBlob(file: File) {
  function fileToArrayBuffer(file: File): Promise<Uint8Array> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()

      reader.onload = function () {
        const arrayBuffer = new Uint8Array(reader.result as any)
        resolve(arrayBuffer)
      }

      reader.onerror = reject

      reader.readAsArrayBuffer(file)
    })
  }

  const buffer = await fileToArrayBuffer(file)
  const blob = new Blob([buffer], { type: 'application/pdf;chartset=UTF-8' })
  return blob
}

fileToBlob(File)

hexToRgb

hex 转 rgba

typescript
/**
 * hex 转rgba
 * @example  console.log(hexToRgb('#ffffff')) // rgb(255,255,255)
 * @param hex
 * @param opacity
 * @returns
 */
export function hexToRgb(hex: string, opacity?: number) {
  const l = 7 - hex.length

  if (l > 0) hex = hex + hex.slice(-1).repeat(l)
  if (l < 0) throw new Error('hex length > 7')

  const result = `${parseInt(`0x${hex.slice(1, 3)}`)},${parseInt(`0x${hex.slice(3, 5)}`)},${parseInt(
    `0x${hex.slice(5, 7)}`
  )}`
  return opacity ? `rgba(${result},${opacity})` : `rgb(${result})`
}

hexToRgb('#ffffff') // rgb(255,255,255)

rgbToHex

rgb 转 Hex

typescript
/**
 * rgb转Hex
 * @example console.log(rgbToHex('rgb(255,255,255)')) // #ffffff
 * @param style
 * @returns
 */
export function rgbToHex(style: string) {
  type TrimType = 'all' | 'pre' | 'around' | 'post'

  function trim(s: string, type: TrimType = 'around'): string {
    if (type === 'pre') return s.replace(/(^\s*)/g, '')
    if (type === 'post') return s.replace(/(\s*$)/g, '')
    if (type === 'all') return s.replace(/\s+/g, '')
    if (type === 'around') return s.replace(/(^\s*)|(\s*$)/g, '')
    return s
  }

  const reg = /rgb\(([\w\s,]+)\)/

  const matcher = style.match(reg)
  if (!matcher) return
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [_, color] = matcher
  const [r, g, b] = trim(color, 'all').split(',')

  return `#${((1 << 24) + (+r << 16) + (+g << 8) + +b).toString(16).slice(1)}`
}

rgbToHex('rgb(255,255,255)') // #ffffff

toArray

如果是数组直接返回否则封装成数组

typescript
/**
 * 如果是数组直接返回否则封装成数组
 * @param { any } array
 * @returns
 */
export function toArray(array: any) {
  return Array.isArray(array) ? array : [array]
}

toArray(1) // [1]

toNumber

转换成数字

typescript
/**
 * 转换成数字
 * @param {  number | string | boolean | undefined | null } val
 * @returns 数字
 */
export const toNumber = (val: number | string | boolean | undefined | null): number => {
  function isString(o: any): o is string {
    return typeof o === 'string'
  }

  function isBool(value: any): value is boolean {
    return typeof value === 'boolean'
  }

  if (val == null) return 0

  if (isString(val)) {
    val = parseFloat(val)
    val = Number.isNaN(val) ? 0 : val
    return val
  }

  if (isBool(val)) return Number(val)

  return val
}

toNumber('111') // 111

byteToFileSize

将字节转换为合理的容量单位

typescript
/**
 * 将字节转换为合理的容量单位
 * @param bytes
 * @returns
 */
export function byteToFileSize(bytes: number) {
  let BYTES = bytes
  const thresh = 1024
  if (Math.abs(BYTES) < thresh) {
    return `${BYTES} B`
  }
  const units = ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  let u = -1
  const r = 10 ** 1
  do {
    BYTES /= thresh
    u += 1
  } while (Math.round(Math.abs(BYTES) * r) / r >= thresh && u < units.length - 1)
  return `${BYTES.toFixed(1)} ${units[u]}`
}

byteToFileSize(1024000000) // 976.6 MB

toAbsolutePath

将相对路径转换为绝对路径

typescript
import process from 'process'
import path from 'path'

/**
 *
 * @param { string } url 路径
 * @returns 绝对路径
 */
export function toAbsolutePath(url: string): string {
  function isAbsolute(url: string): boolean {
    return /^\/|^\\|^[a-zA-Z]:[/\\]/.test(url)
  }

  return isAbsolute(url) ? url : path.resolve(process.cwd(), url)
}

toAbsolutePath('/a/b/c') // http://localhost:8080/a/b/c

toObject

将数组转换成对象

typescript
export function toObject(arr: Array<any>, filter?: string[]): object {
  function isPlainObject(o: any): o is Record<any, any> {
    return Object.prototype.toString.call(o) === '[object Object]'
  }

  return arr.reduce(
    (result, item) =>
      !isPlainObject(item)
        ? result
        : Object.keys(item).reduce((result, key) => {
            if (filter && !filter.includes(key)) return result
            if (!result[key]) result[key] = []
            result[key].push(item[key])
            return result
          }, result),
    {} as Record<string, any>
  )
}

/**
 * @param { Array<any> } arr 数组
 * @param { string[] = [] } filter 保留filter中的key
 * @return { boolean }
 */

const arr = [
  {
    a: 1,
  },
  {
    a: 3,
    3: 5,
  },
]
const data = toObject(arr, ['a']) // { a: [ 1, 3 ] }

Released under the MIT License.