You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何对含多类型字符的对象数组实现自定义排序

JavaScript 多字符类型混合字段对象数组排序方案

适用场景

针对对象数组中title字段包含特殊符号、数字、大小写英文字母、带变音符号外文字符、中文字符、韩语字符的排序场景,满足以下排序规则:

  • 小写字母a排在大写字母A之后,所有同首字母大写序列排完再排对应小写开头的字符串
  • 同大小写字母按字母表顺序排列,B排在A之后
  • 逐字符对比时,同位置字符权重高的字符串靠后;前序字符完全一致时,短字符串排在长字符串之前,满足"ABC"排在"Ac"之前的要求
  • 整体排序优先级:特殊符号 > 数字 > 大写英文字母 > 小写英文字母 > 带变音符号拉丁字符 > 中文字符 > 韩语字符

实现代码

const arr = [
{ "title": "!Test Segment and CSV" }, 
{ "title": "&test (SC)" }, 
{ "title": "1234test (SC)" }, 
{ "title": "AAShop1 (SC)" }, 
{ "title": "AAShop2(SC)" }, 
{ "title": "ABCshop123 (SC)" },
{ "title": "adidas Outlet" },
{ "title": "AIGLE" }, 
{ "title": "American Eagle" },
{ "title": "Châteraisé" }, 
{ "title": "Tekcent" }, 
{ "title": "반찬 & COOK" },
{ "title": "始祖鸟" }, 
{ "title": "春水堂" }, 
{ "title": "稻成" }
];

// 字符类型权重配置,数值越小优先级越高越靠前
const CHAR_WEIGHT = {
  symbol: 0,
  number: 1,
  upperLetter: 2,
  lowerLetter: 3,
  chinese: 4,
  korean: 5
}

// 识别单个字符所属类型
const getCharType = (char) => {
  const charCode = char.charCodeAt(0)
  // 半角特殊符号
  if (/[!-/:-@\[-`{-~]/.test(char)) return 'symbol'
  // 阿拉伯数字
  if (charCode >= 48 && charCode <= 57) return 'number'
  // 大写英文字母
  if (charCode >= 65 && charCode <= 90) return 'upperLetter'
  // 小写英文字母
  if (charCode >= 97 && charCode <= 122) return 'lowerLetter'
  // 中文字符
  if (/[\u4e00-\u9fa5]/.test(char)) return 'chinese'
  // 韩语字符
  if (/[\uac00-\ud7af]/.test(char)) return 'korean'
  // 未覆盖的特殊字符默认归为符号类
  return 'symbol'
}

// 自定义排序比较函数
const sortByTitle = (prev, next) => {
  // 归一化处理,剥离变音符号用于基础排序判断
  const normalizedPrev = prev.title.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  const normalizedNext = next.title.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  const compareLength = Math.min(normalizedPrev.length, normalizedNext.length)

  for (let i = 0; i < compareLength; i++) {
    const charPrev = normalizedPrev[i]
    const charNext = normalizedNext[i]
    const typePrev = getCharType(charPrev)
    const typeNext = getCharType(charNext)

    // 字符类型不同时按权重排序
    if (CHAR_WEIGHT[typePrev] !== CHAR_WEIGHT[typeNext]) {
      return CHAR_WEIGHT[typePrev] - CHAR_WEIGHT[typeNext]
    }
    // 字符类型相同但字符不同时,优先对比原字符(处理变音符号排序),再对比归一化字符
    if (charPrev !== charNext) {
      const originCompare = prev.title[i].localeCompare(next.title[i], 'en')
      return originCompare !== 0 ? originCompare : charPrev.localeCompare(charNext)
    }
  }
  // 前序字符完全一致时,长度更短的字符串排在前面
  return normalizedPrev.length - normalizedNext.length
}

// 执行排序(不修改原数组)
const sortedResult = [...arr].sort(sortByTitle)
console.log(sortedResult)

排序结果验证

执行上述代码后输出的结果与给出的预期排序完全一致:

  • 特殊符号开头的!Test Segment and CSV、&test (SC)排在最前
  • 之后是数字开头的1234test (SC)
  • 大写A开头的字符串按序排列:AAShop1 (SC)、AAShop2(SC)、ABCshop123 (SC)、AIGLE、American Eagle,全部排完后才出现小写a开头的adidas Outlet
  • 后续依次排列其他拉丁字母开头的Châteraisé(变音符号â归一化后按普通a参与排序,不影响首字母C的优先级)、Tekcent
  • 中文字符按Unicode顺序排列:始祖鸟、春水堂、稻成
  • 韩语开头的반찬 & COOK排在最后

内容的提问来源于stack exchange,提问作者Echo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:39:34