技术

前端字符串排序

三种常用的排序方式

自带的sort:

  • unicode码点对比

手写:

  • 正则、filter出需要的部分进行排序

Eg.

export const sortListMultiLevel = (a: any, b: any) => {
  const getSegments = (localId: string): number[] => {
    if (!localId) {
      return []
    }
    // 去掉元素类型前缀,例如 FUNC-1-2 => [1, 2],按照层级比较
    const [, ...numParts] = localId.split('-')
    return numParts.map((part) => Number(part))
  }

  const aSegs = getSegments(a?.extend?.localId || '')
  const bSegs = getSegments(b?.extend?.localId || '')

  const maxLen = Math.max(aSegs.length, bSegs.length)
  for (let i = 0; i < maxLen; i++) {
    const diff = (aSegs[i] || 0) - (bSegs[i] || 0)
    if (diff !== 0) {
      return diff
    }
  }
  return aSegs.length - bSegs.length
}

Eg.

export const sortFunctionListWithParentChild = (
  functionList: any[],
  order: 'ascend' | 'descend' = 'ascend',
) => {
  if (!functionList || functionList.length === 0) {
    return []
  }
  const collator = new Intl.Collator(undefined, {
    numeric: true,
    sensitivity: 'base'
  })
  const direction = order === 'descend' ? -1 : 1
  const compareLocalId = (aLocalId: string, bLocalId: string) => direction * collator.compare(aLocalId, bLocalId)

  const parentFunctions = functionList.filter(item => !item?.fn?.extend?.isSubFunction)
  const subFunctions = functionList.filter(item => item?.fn?.extend?.isSubFunction)
  parentFunctions.sort((a, b) => {
    const aLocalId = a?.extend?.localId || ''
    const bLocalId = b?.extend?.localId || ''
    return compareLocalId(aLocalId, bLocalId)
  })
  const result: any[] = []
  parentFunctions.forEach(parentFunc => {
    result.push(parentFunc)
    const parentSubFunctions = subFunctions.filter(subFunc => {
      return (
        parentFunc.fn.subFunctions &&
        parentFunc.fn.subFunctions.some((sub: any) => sub.id === subFunc.id)
      )
    })
    parentSubFunctions.sort((a, b) => {
      const aLocalId = a?.extend?.localId || ''
      const bLocalId = b?.extend?.localId || ''
      return compareLocalId(aLocalId, bLocalId)
    })
    result.push(...parentSubFunctions)
  })

  return result
}